From 02b45321e0464b3cbbc57c4947f8a11fa78498df Mon Sep 17 00:00:00 2001 From: Tien Nguyen Date: Thu, 23 Jan 2025 21:04:03 -0500 Subject: [PATCH] fix issue relate to os_expression does not distinguished between null and empty string Signed-off-by: Tien Nguyen --- .../os_expression.tf | 35 +++++++++++++++++ .../os_expression_updated.tf | 34 +++++++++++++++++ okta/resource_okta_app_signon_policy_rule.go | 26 ++++++++----- ...source_okta_app_signon_policy_rule_test.go | 38 +++++++++++++++++++ ...nditionEvaluatorPlatformOperatingSystem.go | 2 +- 5 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 examples/resources/okta_app_signon_policy_rule/os_expression.tf create mode 100644 examples/resources/okta_app_signon_policy_rule/os_expression_updated.tf diff --git a/examples/resources/okta_app_signon_policy_rule/os_expression.tf b/examples/resources/okta_app_signon_policy_rule/os_expression.tf new file mode 100644 index 000000000..d4a9de5c9 --- /dev/null +++ b/examples/resources/okta_app_signon_policy_rule/os_expression.tf @@ -0,0 +1,35 @@ +resource "okta_app_signon_policy" "test" { + name = "testAcc_Test_App_replace_with_uuid" + description = "The app signon policy used by our test app" +} + +resource "okta_app_signon_policy_rule" "test" { + access = "ALLOW" + constraints = ["{\"knowledge\":{\"reauthenticateIn\":\"PT0S\",\"types\":[\"password\"],\"required\":true},\"possession\":{\"excludedAuthenticationMethods\":[{\"key\":\"okta_email\",\"method\":\"email\"},{\"key\":\"phone_number\",\"method\":\"sms\"},{\"key\":\"phone_number\",\"method\":\"voice\"}],\"required\":false,\"userPresence\":\"REQUIRED\",\"userVerification\":\"OPTIONAL\"}}"] + custom_expression = null + device_assurances_included = null + device_is_managed = null + device_is_registered = null + factor_mode = "2FA" + groups_excluded = null + groups_included = null + inactivity_period = null + name = "test1" + network_connection = "ANYWHERE" + network_excludes = null + network_includes = null + policy_id = okta_app_signon_policy.test.id + priority = 0 + re_authentication_frequency = "PT0S" + status = "ACTIVE" + type = "ASSURANCE" + user_types_excluded = [] + user_types_included = [] + users_excluded = [] + users_included = [] + platform_include { + os_expression = "" + os_type = "OTHER" + type = "DESKTOP" + } +} diff --git a/examples/resources/okta_app_signon_policy_rule/os_expression_updated.tf b/examples/resources/okta_app_signon_policy_rule/os_expression_updated.tf new file mode 100644 index 000000000..adafd2e77 --- /dev/null +++ b/examples/resources/okta_app_signon_policy_rule/os_expression_updated.tf @@ -0,0 +1,34 @@ +resource "okta_app_signon_policy" "test" { + name = "testAcc_Test_App_replace_with_uuid" + description = "The app signon policy used by our test app" +} + +resource "okta_app_signon_policy_rule" "test" { + access = "ALLOW" + constraints = ["{\"knowledge\":{\"reauthenticateIn\":\"PT0S\",\"types\":[\"password\"],\"required\":true},\"possession\":{\"excludedAuthenticationMethods\":[{\"key\":\"okta_email\",\"method\":\"email\"},{\"key\":\"phone_number\",\"method\":\"sms\"},{\"key\":\"phone_number\",\"method\":\"voice\"}],\"required\":false,\"userPresence\":\"REQUIRED\",\"userVerification\":\"OPTIONAL\"}}"] + custom_expression = null + device_assurances_included = null + device_is_managed = null + device_is_registered = null + factor_mode = "2FA" + groups_excluded = null + groups_included = null + inactivity_period = null + name = "test1" + network_connection = "ANYWHERE" + network_excludes = null + network_includes = null + policy_id = okta_app_signon_policy.test.id + priority = 0 + re_authentication_frequency = "PT0S" + status = "ACTIVE" + type = "ASSURANCE" + user_types_excluded = [] + user_types_included = [] + users_excluded = [] + users_included = [] + platform_include { + os_type = "IOS" + type = "MOBILE" + } +} diff --git a/okta/resource_okta_app_signon_policy_rule.go b/okta/resource_okta_app_signon_policy_rule.go index dc6ef04b2..bfba5165e 100644 --- a/okta/resource_okta_app_signon_policy_rule.go +++ b/okta/resource_okta_app_signon_policy_rule.go @@ -461,10 +461,13 @@ func buildAccessPolicyPlatformInclude(d *schema.ResourceData) []*sdk.PlatformCon valueList := v.(*schema.Set).List() for _, item := range valueList { if value, ok := item.(map[string]interface{}); ok { - var expr string + var expr *string if typ := getMapString(value, "os_type"); typ == "OTHER" { - if v := getMapString(value, "os_expression"); v != "" { - expr = v + if v, ok := value["os_expression"]; ok { + if v != nil { + res := v.(string) + expr = &res + } } } includeList = append(includeList, &sdk.PlatformConditionEvaluatorPlatform{ @@ -483,15 +486,18 @@ func flattenAccessPolicyPlatformInclude(platform *sdk.PlatformPolicyRuleConditio var flattened []interface{} if platform != nil && platform.Include != nil { for _, v := range platform.Include { - var expr string - if v.Os.Expression != "" { + var expr *string + if v.Os.Expression != nil { expr = v.Os.Expression } - flattened = append(flattened, map[string]interface{}{ - "os_expression": expr, - "os_type": v.Os.Type, - "type": v.Type, - }) + m := map[string]interface{}{ + "os_type": v.Os.Type, + "type": v.Type, + } + if expr != nil { + m["os_expression"] = *expr + } + flattened = append(flattened, m) } } return schema.NewSet(schema.HashResource(platformIncludeResource), flattened) diff --git a/okta/resource_okta_app_signon_policy_rule_test.go b/okta/resource_okta_app_signon_policy_rule_test.go index 32e10de30..1c22bcf4e 100644 --- a/okta/resource_okta_app_signon_policy_rule_test.go +++ b/okta/resource_okta_app_signon_policy_rule_test.go @@ -358,3 +358,41 @@ func TestAccResourceOktaAppSignOnPolicyRuleDefault(t *testing.T) { }, }) } + +func TestAccResourceOktaAppSignOnPolicyRuleOsExpression(t *testing.T) { + resourceName := fmt.Sprintf("%s.test", appSignOnPolicyRule) + mgr := newFixtureManager("resources", appSignOnPolicyRule, t.Name()) + config := mgr.GetFixtures("os_expression.tf", t) + updatedConfig := mgr.GetFixtures("os_expression_updated.tf", t) + + oktaResourceTest(t, resource.TestCase{ + PreCheck: testAccPreCheck(t), + ErrorCheck: testAccErrorChecks(t), + ProtoV5ProviderFactories: testAccMergeProvidersFactories, + CheckDestroy: checkAppSignOnPolicyRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", "test1"), + resource.TestCheckResourceAttr(resourceName, "status", statusActive), + resource.TestCheckResourceAttr(resourceName, "platform_include.#", "1"), + resource.TestCheckResourceAttr(resourceName, "platform_include.0.os_expression", ""), + resource.TestCheckResourceAttr(resourceName, "platform_include.0.os_type", "OTHER"), + resource.TestCheckResourceAttr(resourceName, "platform_include.0.type", "DESKTOP"), + ), + }, + { + Config: updatedConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", "test1"), + resource.TestCheckResourceAttr(resourceName, "status", statusActive), + resource.TestCheckResourceAttr(resourceName, "platform_include.#", "1"), + resource.TestCheckResourceAttr(resourceName, "platform_include.0.os_expression", ""), + resource.TestCheckResourceAttr(resourceName, "platform_include.0.os_type", "IOS"), + resource.TestCheckResourceAttr(resourceName, "platform_include.0.type", "MOBILE"), + ), + }, + }, + }) +} diff --git a/sdk/v2_platformConditionEvaluatorPlatformOperatingSystem.go b/sdk/v2_platformConditionEvaluatorPlatformOperatingSystem.go index a26840aaa..d3512e29e 100644 --- a/sdk/v2_platformConditionEvaluatorPlatformOperatingSystem.go +++ b/sdk/v2_platformConditionEvaluatorPlatformOperatingSystem.go @@ -2,7 +2,7 @@ package sdk type PlatformConditionEvaluatorPlatformOperatingSystem struct { - Expression string `json:"expression"` + Expression *string `json:"expression"` Type string `json:"type,omitempty"` Version *PlatformConditionEvaluatorPlatformOperatingSystemVersion `json:"version,omitempty"` }