From c6d2abcd4afe78d92fd285e5c77fecdfe806ed5d Mon Sep 17 00:00:00 2001 From: Jake Van Vorhis <83739412+jakedoublev@users.noreply.github.com> Date: Tue, 1 Oct 2024 07:21:01 -0700 Subject: [PATCH] feat(ci): add tests for subject condition sets, and --force delete flag (#389) Resolves #331 --- cmd/policy-subjectConditionSets.go | 10 +- .../policy/subject-condition-sets/delete.md | 2 + e2e/subject-condition-sets.bats | 123 +++++++++++++++++- 3 files changed, 128 insertions(+), 7 deletions(-) diff --git a/cmd/policy-subjectConditionSets.go b/cmd/policy-subjectConditionSets.go index 3835bedb..dd69e13e 100644 --- a/cmd/policy-subjectConditionSets.go +++ b/cmd/policy-subjectConditionSets.go @@ -248,13 +248,16 @@ func policy_deleteSubjectConditionSet(cmd *cobra.Command, args []string) { defer h.Close() id := c.Flags.GetRequiredID("id") + force := c.Flags.GetOptionalBool("force") scs, err := h.GetSubjectConditionSet(id) if err != nil { cli.ExitWithError(fmt.Sprintf("Subject Condition Set with id %s not found", id), err) } - cli.ConfirmAction(cli.ActionDelete, "Subject Condition Set", id, false) + if !force { + cli.ConfirmAction(cli.ActionDelete, "Subject Condition Set", id, false) + } if err := h.DeleteSubjectConditionSet(id); err != nil { cli.ExitWithError(fmt.Sprintf("Subject Condition Set with id %s not found", id), err) @@ -345,6 +348,11 @@ func init() { deleteDoc.GetDocFlag("id").Default, deleteDoc.GetDocFlag("id").Description, ) + deleteDoc.Flags().Bool( + deleteDoc.GetDocFlag("force").Name, + false, + deleteDoc.GetDocFlag("force").Description, + ) doc := man.Docs.GetCommand("policy/subject-condition-sets", man.WithSubcommands( diff --git a/docs/man/policy/subject-condition-sets/delete.md b/docs/man/policy/subject-condition-sets/delete.md index 9a075c0f..9726e6e0 100644 --- a/docs/man/policy/subject-condition-sets/delete.md +++ b/docs/man/policy/subject-condition-sets/delete.md @@ -8,6 +8,8 @@ command: description: The ID of the subject condition set to delete shorthand: i required: true + - name: force + description: Force deletion without interactive confirmation (dangerous) --- For more information about subject condition sets, see the `subject-condition-sets` subcommand. diff --git a/e2e/subject-condition-sets.bats b/e2e/subject-condition-sets.bats index 4377b2f2..3dc3c0a2 100755 --- a/e2e/subject-condition-sets.bats +++ b/e2e/subject-condition-sets.bats @@ -2,14 +2,125 @@ # Tests for subject condition sets -# Create scs +setup_file() { + echo -n '{"clientId":"opentdf","clientSecret":"secret"}' > creds.json + export WITH_CREDS='--with-client-creds-file ./creds.json' + export HOST='--host http://localhost:8080' -# Get scs + export SCS_1='[{"condition_groups":[{"conditions":[{"operator":1,"subject_external_values":["marketing"],"subject_external_selector_value":".org.name"},{"operator":1,"subject_external_values":["ShinyThing"],"subject_external_selector_value":".team.name"}],"boolean_operator":1}]}]' + export SCS_2='[{"condition_groups":[{"conditions":[{"operator":3,"subject_external_values":["piedpiper.com","hooli.com"],"subject_external_selector_value":".emailAddress"},{"operator":1,"subject_external_values":["sales"],"subject_external_selector_value":".department"}],"boolean_operator":2}]}]' + export SCS_3='[{"condition_groups":[{"conditions":[{"operator":2,"subject_external_values":["CoolTool","RadService"],"subject_external_selector_value":".team.name"}],"boolean_operator":2}]}]' +} -# Update scs +setup() { + load "${BATS_LIB_PATH}/bats-support/load.bash" + load "${BATS_LIB_PATH}/bats-assert/load.bash" -# List scs + # invoke binary with credentials + run_otdfctl_scs () { + run sh -c "./otdfctl $HOST $WITH_CREDS policy subject-condition-sets $*" + } -# Delete scs + run_delete_scs () { + # Capture the first argument as the ID + local id="$1" -# Cleanup - delete everything \ No newline at end of file + run sh -c "./otdfctl $HOST $WITH_CREDS policy scs delete --id $id --force" + } +} + +teardown_file() { + # clear out all test env vars + unset HOST WITH_CREDS NS_NAME NS_ID ATTR_NAME_RANDOM + + rm scs.json +} + +@test "Create a Subject Condition Set (SCS) - from file" { + echo -n "$SCS_1" > scs.json + + run_otdfctl_scs create --subject-sets-file-json scs.json -l fromfile=true + assert_success + assert_output --partial "Id" + assert_output --partial "SubjectSets" + assert_output --partial ".org.name" + assert_output --partial "SUBJECT_MAPPING_OPERATOR_ENUM_IN" + assert_output --regexp "fromfile: true" +} + +@test "Create a Subject Condition Set (SCS) - from flag value JSON" { + run ./otdfctl $HOST $WITH_CREDS policy scs create --subject-sets "$SCS_2" + assert_success + assert_output --partial "Id" + assert_output --partial "SubjectSets" + assert_output --partial ".emailAddress" + assert_output --partial "SUBJECT_MAPPING_OPERATOR_ENUM_IN" +} + +@test "Get a SCS" { + CREATED_ID=$(./otdfctl $HOST $WITH_CREDS policy scs add -s "$SCS_3" -l hello=world --json | jq -r '.id') + run_otdfctl_scs get --id "$CREATED_ID" + assert_success + assert_output --regexp "Id.*$CREATED_ID" + assert_output --partial "Labels" + assert_output --partial "hello: world" + assert_output --partial "Created At" + assert_output --partial "Updated At" + assert_output --partial ".team.name" + assert_output --partial "SUBJECT_MAPPING_OPERATOR_ENUM_NOT_IN" + + run_delete_scs "$CREATED_ID" +} + +@test "Update a SCS - from flag value JSON" { + echo -n "$SCS_1" > scs.json + CREATED_ID=$(./otdfctl $HOST $WITH_CREDS policy scs create --subject-sets-file-json scs.json -l fromfile=true --json | jq -r '.id') + + run ./otdfctl $HOST $WITH_CREDS policy scs update --subject-sets "$SCS_2" --id "$CREATED_ID" + assert_success + assert_output --partial ".emailAddress" + assert_output --partial "SUBJECT_MAPPING_OPERATOR_ENUM_IN" + assert_output --partial "fromfile: true" + refute_output --partial ".org.name" + + run_delete_scs "$CREATED_ID" +} + +@test "Update a SCS - from file" { + CREATED_ID=$(./otdfctl $HOST $WITH_CREDS policy scs create --subject-sets "$SCS_2" -l fromfile=false --json | jq -r '.id') + + echo -n "$SCS_3" > scs.json + + run ./otdfctl $HOST $WITH_CREDS policy scs update --subject-sets-file-json scs.json --id "$CREATED_ID" -l fromfile=true + assert_success + refute_output --partial ".emailAddress" + refute_output --partial "SUBJECT_MAPPING_OPERATOR_ENUM_IN" + assert_output --partial ".team.name" + assert_output --partial "fromfile: true" + assert_output --partial "SUBJECT_MAPPING_OPERATOR_ENUM_NOT_IN" + + run_delete_scs "$CREATED_ID" +} + +@test "List SCS" { + CREATED_ID=$(./otdfctl $HOST $WITH_CREDS policy scs create --subject-sets "$SCS_2" -l fromfile=false --json | jq -r '.id') + + run_otdfctl_scs list + assert_success + assert_output --partial "$CREATED_ID" + + run_otdfctl_scs list --json + assert_success + assert_output --partial ".department" + assert_output --partial ".emailAddress" + assert_output --partial ".team.name" + assert_output --partial ".org.name" + [ $(echo "$output" | jq -r '.[-1].subject_sets[0].condition_groups[0].conditions[0].subject_external_values[0]') = "piedpiper.com" ] + [ $(echo "$output" | jq -r '.[-1].id') = "$CREATED_ID" ] + [ $(echo "$output" | jq -r '.[-1].metadata.labels.fromfile') = "false" ] + + # validate deletion + run_delete_scs "$CREATED_ID" + assert_success + assert_output --partial "$CREATED_ID" +}