From c1a9a9e73ddef2178008b79cccdff9d9fb7070ce Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 22 Nov 2021 21:14:18 +0000 Subject: [PATCH 1/7] Ignore log files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3465d4ef20..590ec8c5f7 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ website/node_modules .*.swp .idea *.iml +*.log *.test website/vendor From 81e2b3e21b42bb8cd955fd47f6c5c7cec1577188 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 22 Nov 2021 21:18:10 +0000 Subject: [PATCH 2/7] azuread_conditional_access_policy: make all enums case insensitive since the API treats them as such --- .../conditional_access_policy_resource.go | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index 503c72fc75..ad253858d9 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/suppress" "github.com/manicminer/hamilton/msgraph" "github.com/manicminer/hamilton/odata" @@ -54,13 +55,14 @@ func conditionalAccessPolicyResource() *schema.Resource { }, "state": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessPolicyStateDisabled, msgraph.ConditionalAccessPolicyStateEnabled, msgraph.ConditionalAccessPolicyStateEnabledForReportingButNotEnforced, - }, false), + }, true), }, "conditions": { @@ -172,8 +174,9 @@ func conditionalAccessPolicyResource() *schema.Resource { }, "client_app_types": { - Type: schema.TypeList, - Required: true, + Type: schema.TypeList, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ @@ -183,7 +186,7 @@ func conditionalAccessPolicyResource() *schema.Resource { "exchangeActiveSync", "easSupported", "other", - }, false), + }, true), }, }, @@ -224,7 +227,8 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Required: true, Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeString, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "all", "android", @@ -233,7 +237,7 @@ func conditionalAccessPolicyResource() *schema.Resource { "unknownFutureValue", "windows", "windowsPhone", - }, false), + }, true), }, }, @@ -241,7 +245,8 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeString, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "all", "android", @@ -250,7 +255,7 @@ func conditionalAccessPolicyResource() *schema.Resource { "unknownFutureValue", "windows", "windowsPhone", - }, false), + }, true), }, }, }, @@ -261,7 +266,8 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeString, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "hidden", "high", @@ -269,7 +275,7 @@ func conditionalAccessPolicyResource() *schema.Resource { "medium", "none", "unknownFutureValue", - }, false), + }, true), }, }, @@ -277,7 +283,8 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeString, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "hidden", "high", @@ -285,7 +292,7 @@ func conditionalAccessPolicyResource() *schema.Resource { "medium", "none", "unknownFutureValue", - }, false), + }, true), }, }, }, @@ -307,7 +314,8 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Required: true, Elem: &schema.Schema{ - Type: schema.TypeString, + Type: schema.TypeString, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "approvedApplication", "block", @@ -317,7 +325,7 @@ func conditionalAccessPolicyResource() *schema.Resource { "mfa", "passwordChange", "unknownFutureValue", - }, false), + }, true), }, }, @@ -354,14 +362,15 @@ func conditionalAccessPolicyResource() *schema.Resource { }, "cloud_app_security_policy": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ "blockDownloads", "mcasConfigured", "monitorOnly", "unknownFutureValue", - }, false), + }, true), }, "sign_in_frequency": { From 4705fb07cb5797db31400c16a9f727007479e036 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 22 Nov 2021 21:26:08 +0000 Subject: [PATCH 3/7] Reflect new API handling of sessionControls property --- .../conditional_access_policy_resource.go | 4 +-- ...conditional_access_policy_resource_test.go | 25 +++++++++---------- .../conditionalaccess/conditionalaccess.go | 24 +----------------- 3 files changed, 15 insertions(+), 38 deletions(-) diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index ad253858d9..4cf2d9f5c2 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -430,7 +430,7 @@ func conditionalAccessPolicyResourceCreate(ctx context.Context, d *schema.Resour State: utils.String(d.Get("state").(string)), Conditions: expandConditionalAccessConditionSet(d.Get("conditions").([]interface{})), GrantControls: expandConditionalAccessGrantControls(d.Get("grant_controls").([]interface{})), - SessionControls: expandConditionalAccessSessionControls(d.Get("session_controls").([]interface{}), true), + SessionControls: expandConditionalAccessSessionControls(d.Get("session_controls").([]interface{})), } policy, _, err := client.Create(ctx, properties) @@ -456,7 +456,7 @@ func conditionalAccessPolicyResourceUpdate(ctx context.Context, d *schema.Resour State: utils.String(d.Get("state").(string)), Conditions: expandConditionalAccessConditionSet(d.Get("conditions").([]interface{})), GrantControls: expandConditionalAccessGrantControls(d.Get("grant_controls").([]interface{})), - SessionControls: expandConditionalAccessSessionControls(d.Get("session_controls").([]interface{}), false), + SessionControls: expandConditionalAccessSessionControls(d.Get("session_controls").([]interface{})), } if _, err := client.Update(ctx, properties); err != nil { diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go index 331688cba4..b22cb25f79 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go @@ -84,8 +84,8 @@ func TestAccConditionalAccessPolicy_update(t *testing.T) { } func TestAccConditionalAccessPolicy_sessionControls(t *testing.T) { - // This should continue to pass when https://github.com/microsoftgraph/msgraph-metadata/issues/93 - // is resolved and the conditional ForceNew workaround has been removed + // This is in a separate test to avoid ForceNew in the update test due to https://github.com/microsoftgraph/msgraph-metadata/issues/93 + // session_controls can be added to the complete config, and this rest removed, when this issue is resolved data := acceptance.BuildTestData(t, "azuread_conditional_access_policy", "test") r := ConditionalAccessPolicyResource{} @@ -139,6 +139,8 @@ func TestAccConditionalAccessPolicy_sessionControls(t *testing.T) { } func TestAccConditionalAccessPolicy_sessionControlsDisabled(t *testing.T) { + // Remove this test when https://github.com/microsoftgraph/msgraph-metadata/issues/93 is resolved + data := acceptance.BuildTestData(t, "azuread_conditional_access_policy", "test") r := ConditionalAccessPolicyResource{} @@ -206,7 +208,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["all"] + included_platforms = ["All"] } users { @@ -245,7 +247,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["android"] + included_platforms = ["Android"] excluded_platforms = ["iOS"] } @@ -260,12 +262,6 @@ resource "azuread_conditional_access_policy" "test" { built_in_controls = ["mfa"] } - session_controls { - application_enforced_restrictions_enabled = true - cloud_app_security_policy = "monitorOnly" - sign_in_frequency = 10 - sign_in_frequency_period = "hours" - } } `, data.RandomInteger) } @@ -288,7 +284,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["all"] + included_platforms = ["All"] } users { @@ -303,7 +299,10 @@ resource "azuread_conditional_access_policy" "test" { } session_controls { - cloud_app_security_policy = "monitorOnly" + application_enforced_restrictions_enabled = true + cloud_app_security_policy = "monitorOnly" + sign_in_frequency = 10 + sign_in_frequency_period = "hours" } } `, data.RandomInteger) @@ -327,7 +326,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["all"] + included_platforms = ["All"] } users { diff --git a/internal/services/conditionalaccess/conditionalaccess.go b/internal/services/conditionalaccess/conditionalaccess.go index f93ea10262..1738cb012e 100644 --- a/internal/services/conditionalaccess/conditionalaccess.go +++ b/internal/services/conditionalaccess/conditionalaccess.go @@ -306,27 +306,9 @@ func expandConditionalAccessGrantControls(in []interface{}) *msgraph.Conditional return &result } -func expandConditionalAccessSessionControls(in []interface{}, create bool) *msgraph.ConditionalAccessSessionControls { +func expandConditionalAccessSessionControls(in []interface{}) *msgraph.ConditionalAccessSessionControls { result := msgraph.ConditionalAccessSessionControls{} - if create && (len(in) == 0 || in[0] == nil) { - return &result - } - - // API doesn't accept boolean false values here in POST requests, it should be omitted instead - // When updating, omitting a setting doesn't change it, so we default to false - if !create { - result.ApplicationEnforcedRestrictions = &msgraph.ApplicationEnforcedRestrictionsSessionControl{ - IsEnabled: utils.Bool(false), - } - result.CloudAppSecurity = &msgraph.CloudAppSecurityControl{ - IsEnabled: utils.Bool(false), - } - result.SignInFrequency = &msgraph.SignInFrequencySessionControl{ - IsEnabled: utils.Bool(false), - } - } - if len(in) == 0 || in[0] == nil { return &result } @@ -352,10 +334,6 @@ func expandConditionalAccessSessionControls(in []interface{}, create bool) *msgr } } - // API doesn't accept all disabled settings on POST, instead should be an empty object - if create && !*result.ApplicationEnforcedRestrictions.IsEnabled && !*result.CloudAppSecurity.IsEnabled && !*result.SignInFrequency.IsEnabled { - return &msgraph.ConditionalAccessSessionControls{} - } return &result } From 62fc9d0c7aeaaea432266af961d16784e2f73e3e Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 22 Nov 2021 21:49:02 +0000 Subject: [PATCH 4/7] azuread_conditional_access_policy: use SDK constants for enum validation --- .../conditional_access_policy_resource.go | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index 4cf2d9f5c2..bd1ca7dd52 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -180,12 +180,12 @@ func conditionalAccessPolicyResource() *schema.Resource { Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ - "all", - "browser", - "mobileAppsAndDesktopClients", - "exchangeActiveSync", - "easSupported", - "other", + msgraph.ConditionalAccessClientAppTypeAll, + msgraph.ConditionalAccessClientAppTypeBrowser, + msgraph.ConditionalAccessClientAppTypeEasSupported, + msgraph.ConditionalAccessClientAppTypeExchangeActiveSync, + msgraph.ConditionalAccessClientAppTypeMobileAppsAndDesktopClients, + msgraph.ConditionalAccessClientAppTypeOther, }, true), }, }, @@ -230,13 +230,13 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeString, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - "all", - "android", - "iOS", - "macOS", - "unknownFutureValue", - "windows", - "windowsPhone", + msgraph.ConditionalAccessDevicePlatformAll, + msgraph.ConditionalAccessDevicePlatformAndroid, + msgraph.ConditionalAccessDevicePlatformIos, + msgraph.ConditionalAccessDevicePlatformMacOs, + msgraph.ConditionalAccessDevicePlatformUnknownFutureValue, + msgraph.ConditionalAccessDevicePlatformWindows, + msgraph.ConditionalAccessDevicePlatformWindowsPhone, }, true), }, }, @@ -248,13 +248,13 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeString, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - "all", - "android", - "iOS", - "macOS", - "unknownFutureValue", - "windows", - "windowsPhone", + msgraph.ConditionalAccessDevicePlatformAll, + msgraph.ConditionalAccessDevicePlatformAndroid, + msgraph.ConditionalAccessDevicePlatformIos, + msgraph.ConditionalAccessDevicePlatformMacOs, + msgraph.ConditionalAccessDevicePlatformUnknownFutureValue, + msgraph.ConditionalAccessDevicePlatformWindows, + msgraph.ConditionalAccessDevicePlatformWindowsPhone, }, true), }, }, @@ -269,12 +269,12 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeString, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - "hidden", - "high", - "low", - "medium", - "none", - "unknownFutureValue", + msgraph.ConditionalAccessRiskLevelHidden, + msgraph.ConditionalAccessRiskLevelHigh, + msgraph.ConditionalAccessRiskLevelLow, + msgraph.ConditionalAccessRiskLevelMedium, + msgraph.ConditionalAccessRiskLevelNone, + msgraph.ConditionalAccessRiskLevelUnknownFutureValue, }, true), }, }, @@ -286,12 +286,12 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeString, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - "hidden", - "high", - "low", - "medium", - "none", - "unknownFutureValue", + msgraph.ConditionalAccessRiskLevelHidden, + msgraph.ConditionalAccessRiskLevelHigh, + msgraph.ConditionalAccessRiskLevelLow, + msgraph.ConditionalAccessRiskLevelMedium, + msgraph.ConditionalAccessRiskLevelNone, + msgraph.ConditionalAccessRiskLevelUnknownFutureValue, }, true), }, }, @@ -317,14 +317,14 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeString, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - "approvedApplication", - "block", - "compliantApplication", - "compliantDevice", - "domainJoinedDevice", - "mfa", - "passwordChange", - "unknownFutureValue", + msgraph.ConditionalAccessGrantControlApprovedApplication, + msgraph.ConditionalAccessGrantControlBlock, + msgraph.ConditionalAccessGrantControlCompliantApplication, + msgraph.ConditionalAccessGrantControlCompliantDevice, + msgraph.ConditionalAccessGrantControlDomainJoinedDevice, + msgraph.ConditionalAccessGrantControlMfa, + msgraph.ConditionalAccessGrantControlPasswordChange, + msgraph.ConditionalAccessGrantControlUnknownFutureValue, }, true), }, }, @@ -366,10 +366,10 @@ func conditionalAccessPolicyResource() *schema.Resource { Optional: true, DiffSuppressFunc: suppress.CaseDifference, ValidateFunc: validation.StringInSlice([]string{ - "blockDownloads", - "mcasConfigured", - "monitorOnly", - "unknownFutureValue", + msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeBlockDownloads, + msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeMcasConfigured, + msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeMonitorOnly, + msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeUnknownFutureValue, }, true), }, From 51d22b1ae54774aa6fc0652d40b4d65749c4871b Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Mon, 22 Nov 2021 21:49:36 +0000 Subject: [PATCH 5/7] azuread_conditional_access_policy: support the device_filter block --- docs/resources/conditional_access_policy.md | 21 +++ .../conditional_access_policy_resource.go | 41 ++++++ ...conditional_access_policy_resource_test.go | 132 ++++++++++++++++++ .../conditionalaccess/conditionalaccess.go | 62 ++++++++ 4 files changed, 256 insertions(+) diff --git a/docs/resources/conditional_access_policy.md b/docs/resources/conditional_access_policy.md index 2f4a3abd9e..0a173e1b7b 100644 --- a/docs/resources/conditional_access_policy.md +++ b/docs/resources/conditional_access_policy.md @@ -31,6 +31,13 @@ resource "azuread_conditional_access_policy" "example" { excluded_applications = ["00000004-0000-0ff1-ce00-000000000000"] } + devices { + device_filter { + mode = "exclude" + rule = "device.operatingSystem eq \"Doors\"" + } + } + locations { included_locations = ["All"] excluded_locations = ["AllTrusted"] @@ -87,6 +94,7 @@ The following arguments are supported: * `applications` - (Required) An `applications` block as documented below, which specifies applications and user actions included in and excluded from the policy. * `client_app_types` - (Required) A list of client application types included in the policy. Possible values are: `all`, `browser`, `mobileAppsAndDesktopClients`, `exchangeActiveSync`, `easSupported` and `other`. +* `devices` - (Optional) A `devices` block as documented below, which describes devices to be included in and excluded from the policy. * `locations` - (Required) A `locations` block as documented below, which specifies locations included in and excluded from the policy. * `platforms` - (Required) A `platforms` block as documented below, which specifies platforms included in and excluded from the policy. * `sign_in_risk_levels` - (Optional) A list of sign-in risk levels included in the policy. Possible values are: `low`, `medium`, `high`, `hidden`, `none`, `unknownFutureValue`. @@ -103,6 +111,19 @@ The following arguments are supported: --- +`devices` block supports the following: + +* `device_filter` - (Optional) A `device_filter` block as described below. + +--- + +`device_filter` block supports the following: + +* `mode` - (Required) Whether to include in, or exclude from, matching devices from the policy. Supported values are `include` or `exclude`. +* `rule` - (Required) Condition filter to match devices. For more information, see [official documentation](https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/concept-condition-filters-for-devices#supported-operators-and-device-properties-for-filters). + +--- + `users` block supports the following: * `excluded_groups` - (Optional) A list of group IDs excluded from scope of policy. diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index bd1ca7dd52..881617e36e 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -190,6 +190,40 @@ func conditionalAccessPolicyResource() *schema.Resource { }, }, + "devices": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_filter": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mode": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + msgraph.ConditionalAccessFilterModeExclude, + msgraph.ConditionalAccessFilterModeInclude, + }, true), + }, + + "rule": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validate.NoEmptyStrings, + }, + }, + }, + }, + }, + }, + }, + "locations": { Type: schema.TypeList, Required: true, @@ -402,6 +436,13 @@ func conditionalAccessPolicyCustomizeDiff(ctx context.Context, diff *schema.Reso diff.ForceNew("session_controls.0.sign_in_frequency") } + if old, new := diff.GetChange("conditions.0.devices.#"); old.(int) > 0 && new.(int) == 0 { + diff.ForceNew("conditions.0.devices") + } + if old, new := diff.GetChange("conditions.0.devices.0.device_filter.#"); old.(int) > 0 && new.(int) == 0 { + diff.ForceNew("conditions.0.devices.0.device_filter") + } + return nil } diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go index b22cb25f79..110328bf67 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go @@ -83,6 +83,55 @@ func TestAccConditionalAccessPolicy_update(t *testing.T) { }) } +func TestAccConditionalAccessPolicy_deviceFilter(t *testing.T) { + // This is a separate test for two reasons: + // 1. To accommodate future properties included_devices/excluded_devices which both conflict with device_filter + // 2. Because device_filter is conditionally ForceNew, as the API ignores removal of this property + + data := acceptance.BuildTestData(t, "azuread_conditional_access_policy", "test") + r := ConditionalAccessPolicyResource{} + + data.ResourceTest(t, r, []resource.TestStep{ + { + Config: r.deviceFilter(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("id").Exists(), + check.That(data.ResourceName).Key("display_name").HasValue(fmt.Sprintf("acctest-CONPOLICY-%d", data.RandomInteger)), + check.That(data.ResourceName).Key("state").HasValue("disabled"), + ), + }, + data.ImportStep(), + { + Config: r.complete(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.deviceFilter(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("id").Exists(), + check.That(data.ResourceName).Key("display_name").HasValue(fmt.Sprintf("acctest-CONPOLICY-%d", data.RandomInteger)), + check.That(data.ResourceName).Key("state").HasValue("disabled"), + ), + }, + data.ImportStep(), + { + Config: r.deviceFilterUpdate(data), + Check: resource.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("id").Exists(), + check.That(data.ResourceName).Key("display_name").HasValue(fmt.Sprintf("acctest-CONPOLICY-%d", data.RandomInteger)), + check.That(data.ResourceName).Key("state").HasValue("disabled"), + ), + }, + data.ImportStep(), + }) +} + func TestAccConditionalAccessPolicy_sessionControls(t *testing.T) { // This is in a separate test to avoid ForceNew in the update test due to https://github.com/microsoftgraph/msgraph-metadata/issues/93 // session_controls can be added to the complete config, and this rest removed, when this issue is resolved @@ -261,7 +310,90 @@ resource "azuread_conditional_access_policy" "test" { operator = "OR" built_in_controls = ["mfa"] } +} +`, data.RandomInteger) +} + +func (ConditionalAccessPolicyResource) deviceFilter(data acceptance.TestData) string { + return fmt.Sprintf(` +resource "azuread_conditional_access_policy" "test" { + display_name = "acctest-CONPOLICY-%[1]d" + state = "disabled" + + conditions { + client_app_types = ["browser"] + + applications { + included_applications = ["All"] + } + devices { + device_filter { + mode = "exclude" + rule = "device.operatingSystem eq \"Doors\"" + } + } + + locations { + included_locations = ["All"] + } + + platforms { + included_platforms = ["All"] + } + + users { + included_users = ["All"] + excluded_users = ["GuestsOrExternalUsers"] + } + } + + grant_controls { + operator = "OR" + built_in_controls = ["block"] + } +} +`, data.RandomInteger) +} + +func (ConditionalAccessPolicyResource) deviceFilterUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +resource "azuread_conditional_access_policy" "test" { + display_name = "acctest-CONPOLICY-%[1]d" + state = "disabled" + + conditions { + client_app_types = ["browser"] + + applications { + included_applications = ["All"] + } + + devices { + device_filter { + mode = "exclude" + rule = "device.model eq \"yPhone Z\"" + } + } + + locations { + included_locations = ["All"] + } + + platforms { + included_platforms = ["All"] + } + + users { + included_users = ["All"] + excluded_users = ["GuestsOrExternalUsers"] + } + } + + grant_controls { + operator = "OR" + built_in_controls = ["block"] + } } `, data.RandomInteger) } diff --git a/internal/services/conditionalaccess/conditionalaccess.go b/internal/services/conditionalaccess/conditionalaccess.go index 1738cb012e..f96e95375a 100644 --- a/internal/services/conditionalaccess/conditionalaccess.go +++ b/internal/services/conditionalaccess/conditionalaccess.go @@ -17,6 +17,7 @@ func flattenConditionalAccessConditionSet(in *msgraph.ConditionalAccessCondition "applications": flattenConditionalAccessApplications(in.Applications), "users": flattenConditionalAccessUsers(in.Users), "client_app_types": tf.FlattenStringSlicePtr(in.ClientAppTypes), + "devices": flattenConditionalAccessDevices(in.Devices), "locations": flattenConditionalAccessLocations(in.Locations), "platforms": flattenConditionalAccessPlatforms(in.Platforms), "sign_in_risk_levels": tf.FlattenStringSlicePtr(in.SignInRiskLevels), @@ -56,6 +57,18 @@ func flattenConditionalAccessUsers(in *msgraph.ConditionalAccessUsers) []interfa } } +func flattenConditionalAccessDevices(in *msgraph.ConditionalAccessDevices) []interface{} { + if in == nil { + return []interface{}{} + } + + return []interface{}{ + map[string]interface{}{ + "device_filter": flattenConditionalAccessDeviceFilter(in.DeviceFilter), + }, + } +} + func flattenConditionalAccessLocations(in *msgraph.ConditionalAccessLocations) []interface{} { if in == nil { return []interface{}{} @@ -129,6 +142,19 @@ func flattenConditionalAccessSessionControls(in *msgraph.ConditionalAccessSessio } } +func flattenConditionalAccessDeviceFilter(in *msgraph.ConditionalAccessFilter) []interface{} { + if in == nil { + return []interface{}{} + } + + return []interface{}{ + map[string]interface{}{ + "mode": in.Mode, + "rule": in.Rule, + }, + } +} + func flattenCountryNamedLocation(in *msgraph.CountryNamedLocation) []interface{} { if in == nil { return []interface{}{} @@ -191,6 +217,7 @@ func expandConditionalAccessConditionSet(in []interface{}) *msgraph.ConditionalA applications := config["applications"].([]interface{}) users := config["users"].([]interface{}) clientAppTypes := config["client_app_types"].([]interface{}) + devices := config["devices"].([]interface{}) locations := config["locations"].([]interface{}) platforms := config["platforms"].([]interface{}) signInRiskLevels := config["sign_in_risk_levels"].([]interface{}) @@ -199,6 +226,7 @@ func expandConditionalAccessConditionSet(in []interface{}) *msgraph.ConditionalA result.Applications = expandConditionalAccessApplications(applications) result.Users = expandConditionalAccessUsers(users) result.ClientAppTypes = tf.ExpandStringSlicePtr(clientAppTypes) + result.Devices = expandConditionalAccessDevices(devices) result.Locations = expandConditionalAccessLocations(locations) result.Platforms = expandConditionalAccessPlatforms(platforms) result.SignInRiskLevels = tf.ExpandStringSlicePtr(signInRiskLevels) @@ -268,6 +296,26 @@ func expandConditionalAccessPlatforms(in []interface{}) *msgraph.ConditionalAcce return &result } +func expandConditionalAccessDevices(in []interface{}) *msgraph.ConditionalAccessDevices { + result := msgraph.ConditionalAccessDevices{} + + if len(in) == 0 || in[0] == nil { + // The devices field cannot be empty on POST, and is currently totally ignored when empty on PATCH, + // so for now we'll just return nil here and revisit later. + return nil + } + + config := in[0].(map[string]interface{}) + + deviceFilter := config["device_filter"].([]interface{}) + + if len(deviceFilter) > 0 { + result.DeviceFilter = expandConditionalAccessFilter(deviceFilter) + } + + return &result +} + func expandConditionalAccessLocations(in []interface{}) *msgraph.ConditionalAccessLocations { if len(in) == 0 || in[0] == nil { return nil @@ -334,6 +382,20 @@ func expandConditionalAccessSessionControls(in []interface{}) *msgraph.Condition } } + return &result +} + +func expandConditionalAccessFilter(in []interface{}) *msgraph.ConditionalAccessFilter { + result := msgraph.ConditionalAccessFilter{} + + if len(in) == 0 || in[0] == nil { + return &result + } + + config := in[0].(map[string]interface{}) + + result.Mode = utils.String(config["mode"].(string)) + result.Rule = utils.String(config["rule"].(string)) return &result } From 401f7eebace8d666d266875d9f9735f5c3748265 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 25 Nov 2021 12:47:14 +0000 Subject: [PATCH 6/7] azuread_conditional_access_policy: document conditional forcenew for devices block --- docs/resources/conditional_access_policy.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/resources/conditional_access_policy.md b/docs/resources/conditional_access_policy.md index 0a173e1b7b..62b028a605 100644 --- a/docs/resources/conditional_access_policy.md +++ b/docs/resources/conditional_access_policy.md @@ -32,7 +32,7 @@ resource "azuread_conditional_access_policy" "example" { } devices { - device_filter { + filter { mode = "exclude" rule = "device.operatingSystem eq \"Doors\"" } @@ -94,7 +94,7 @@ The following arguments are supported: * `applications` - (Required) An `applications` block as documented below, which specifies applications and user actions included in and excluded from the policy. * `client_app_types` - (Required) A list of client application types included in the policy. Possible values are: `all`, `browser`, `mobileAppsAndDesktopClients`, `exchangeActiveSync`, `easSupported` and `other`. -* `devices` - (Optional) A `devices` block as documented below, which describes devices to be included in and excluded from the policy. +* `devices` - (Optional) A `devices` block as documented below, which describes devices to be included in and excluded from the policy. A `devices` block can be added to an existing policy, but removing the `devices` block forces a new resource to be created. * `locations` - (Required) A `locations` block as documented below, which specifies locations included in and excluded from the policy. * `platforms` - (Required) A `platforms` block as documented below, which specifies platforms included in and excluded from the policy. * `sign_in_risk_levels` - (Optional) A list of sign-in risk levels included in the policy. Possible values are: `low`, `medium`, `high`, `hidden`, `none`, `unknownFutureValue`. @@ -113,11 +113,11 @@ The following arguments are supported: `devices` block supports the following: -* `device_filter` - (Optional) A `device_filter` block as described below. +* `filter` - (Optional) A `filter` block as described below. A `filter` block can be added to an existing policy, but removing the `filter` block forces a new resource to be created. --- -`device_filter` block supports the following: +`filter` block supports the following: * `mode` - (Required) Whether to include in, or exclude from, matching devices from the policy. Supported values are `include` or `exclude`. * `rule` - (Required) Condition filter to match devices. For more information, see [official documentation](https://docs.microsoft.com/en-us/azure/active-directory/conditional-access/concept-condition-filters-for-devices#supported-operators-and-device-properties-for-filters). From c37e16ec1a6d7a5a2d66f2ca1fb4624dafaf8b54 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 25 Nov 2021 12:49:35 +0000 Subject: [PATCH 7/7] Address review: rename device_filter block, normalize enum casing instead of diffsuppressing it --- go.mod | 2 +- go.sum | 4 +- .../conditional_access_policy_resource.go | 60 ++++++++----------- ...conditional_access_policy_resource_test.go | 20 +++---- .../conditionalaccess/conditionalaccess.go | 4 +- .../manicminer/hamilton/msgraph/valuetypes.go | 2 +- vendor/modules.txt | 2 +- 7 files changed, 42 insertions(+), 52 deletions(-) diff --git a/go.mod b/go.mod index 0ac997ba0a..b6d327f4e2 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/terraform-plugin-sdk/v2 v2.8.0 github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect github.com/klauspost/compress v1.12.2 // indirect - github.com/manicminer/hamilton v0.36.0 + github.com/manicminer/hamilton v0.36.1 github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect diff --git a/go.sum b/go.sum index a732a4ce14..1bc8ad5774 100644 --- a/go.sum +++ b/go.sum @@ -299,8 +299,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/manicminer/hamilton v0.36.0 h1:HBH1yJB2nA0d4ZebF9R8LSZMwkyujNUQr4mnIthUKE4= -github.com/manicminer/hamilton v0.36.0/go.mod h1:IOYn2Dc9SUiZ7Ryw6c8Ay795vPPMnrCZe3MktS447dc= +github.com/manicminer/hamilton v0.36.1 h1:rIHUAYP54u70yGcl1HZjo3/DXx7B6npzVFnDSVduttQ= +github.com/manicminer/hamilton v0.36.1/go.mod h1:IOYn2Dc9SUiZ7Ryw6c8Ay795vPPMnrCZe3MktS447dc= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index 881617e36e..fb87cd89e4 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "github.com/hashicorp/terraform-provider-azuread/internal/tf/suppress" "github.com/manicminer/hamilton/msgraph" "github.com/manicminer/hamilton/odata" @@ -55,14 +54,13 @@ func conditionalAccessPolicyResource() *schema.Resource { }, "state": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, + Required: true, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessPolicyStateDisabled, msgraph.ConditionalAccessPolicyStateEnabled, msgraph.ConditionalAccessPolicyStateEnabledForReportingButNotEnforced, - }, true), + }, false), }, "conditions": { @@ -174,9 +172,8 @@ func conditionalAccessPolicyResource() *schema.Resource { }, "client_app_types": { - Type: schema.TypeList, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeList, + Required: true, Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ @@ -186,7 +183,7 @@ func conditionalAccessPolicyResource() *schema.Resource { msgraph.ConditionalAccessClientAppTypeExchangeActiveSync, msgraph.ConditionalAccessClientAppTypeMobileAppsAndDesktopClients, msgraph.ConditionalAccessClientAppTypeOther, - }, true), + }, false), }, }, @@ -196,20 +193,19 @@ func conditionalAccessPolicyResource() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "device_filter": { + "filter": { Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "mode": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, + Required: true, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessFilterModeExclude, msgraph.ConditionalAccessFilterModeInclude, - }, true), + }, false), }, "rule": { @@ -261,8 +257,7 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Required: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessDevicePlatformAll, msgraph.ConditionalAccessDevicePlatformAndroid, @@ -271,7 +266,7 @@ func conditionalAccessPolicyResource() *schema.Resource { msgraph.ConditionalAccessDevicePlatformUnknownFutureValue, msgraph.ConditionalAccessDevicePlatformWindows, msgraph.ConditionalAccessDevicePlatformWindowsPhone, - }, true), + }, false), }, }, @@ -279,8 +274,7 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessDevicePlatformAll, msgraph.ConditionalAccessDevicePlatformAndroid, @@ -289,7 +283,7 @@ func conditionalAccessPolicyResource() *schema.Resource { msgraph.ConditionalAccessDevicePlatformUnknownFutureValue, msgraph.ConditionalAccessDevicePlatformWindows, msgraph.ConditionalAccessDevicePlatformWindowsPhone, - }, true), + }, false), }, }, }, @@ -300,8 +294,7 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessRiskLevelHidden, msgraph.ConditionalAccessRiskLevelHigh, @@ -309,7 +302,7 @@ func conditionalAccessPolicyResource() *schema.Resource { msgraph.ConditionalAccessRiskLevelMedium, msgraph.ConditionalAccessRiskLevelNone, msgraph.ConditionalAccessRiskLevelUnknownFutureValue, - }, true), + }, false), }, }, @@ -317,8 +310,7 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessRiskLevelHidden, msgraph.ConditionalAccessRiskLevelHigh, @@ -326,7 +318,7 @@ func conditionalAccessPolicyResource() *schema.Resource { msgraph.ConditionalAccessRiskLevelMedium, msgraph.ConditionalAccessRiskLevelNone, msgraph.ConditionalAccessRiskLevelUnknownFutureValue, - }, true), + }, false), }, }, }, @@ -348,8 +340,7 @@ func conditionalAccessPolicyResource() *schema.Resource { Type: schema.TypeList, Required: true, Elem: &schema.Schema{ - Type: schema.TypeString, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessGrantControlApprovedApplication, msgraph.ConditionalAccessGrantControlBlock, @@ -359,7 +350,7 @@ func conditionalAccessPolicyResource() *schema.Resource { msgraph.ConditionalAccessGrantControlMfa, msgraph.ConditionalAccessGrantControlPasswordChange, msgraph.ConditionalAccessGrantControlUnknownFutureValue, - }, true), + }, false), }, }, @@ -396,15 +387,14 @@ func conditionalAccessPolicyResource() *schema.Resource { }, "cloud_app_security_policy": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, + Optional: true, ValidateFunc: validation.StringInSlice([]string{ msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeBlockDownloads, msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeMcasConfigured, msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeMonitorOnly, msgraph.ConditionalAccessCloudAppSecuritySessionControlTypeUnknownFutureValue, - }, true), + }, false), }, "sign_in_frequency": { @@ -439,8 +429,8 @@ func conditionalAccessPolicyCustomizeDiff(ctx context.Context, diff *schema.Reso if old, new := diff.GetChange("conditions.0.devices.#"); old.(int) > 0 && new.(int) == 0 { diff.ForceNew("conditions.0.devices") } - if old, new := diff.GetChange("conditions.0.devices.0.device_filter.#"); old.(int) > 0 && new.(int) == 0 { - diff.ForceNew("conditions.0.devices.0.device_filter") + if old, new := diff.GetChange("conditions.0.devices.0.filter.#"); old.(int) > 0 && new.(int) == 0 { + diff.ForceNew("conditions.0.devices.0.filter") } return nil diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go index 110328bf67..c54706eb7c 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go @@ -85,8 +85,8 @@ func TestAccConditionalAccessPolicy_update(t *testing.T) { func TestAccConditionalAccessPolicy_deviceFilter(t *testing.T) { // This is a separate test for two reasons: - // 1. To accommodate future properties included_devices/excluded_devices which both conflict with device_filter - // 2. Because device_filter is conditionally ForceNew, as the API ignores removal of this property + // 1. To accommodate future properties included_devices/excluded_devices which both conflict with devices.0.filter + // 2. Because devices.0.filter is conditionally ForceNew, as the API ignores removal of this property data := acceptance.BuildTestData(t, "azuread_conditional_access_policy", "test") r := ConditionalAccessPolicyResource{} @@ -257,7 +257,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["All"] + included_platforms = ["all"] } users { @@ -296,7 +296,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["Android"] + included_platforms = ["android"] excluded_platforms = ["iOS"] } @@ -328,7 +328,7 @@ resource "azuread_conditional_access_policy" "test" { } devices { - device_filter { + filter { mode = "exclude" rule = "device.operatingSystem eq \"Doors\"" } @@ -339,7 +339,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["All"] + included_platforms = ["all"] } users { @@ -370,7 +370,7 @@ resource "azuread_conditional_access_policy" "test" { } devices { - device_filter { + filter { mode = "exclude" rule = "device.model eq \"yPhone Z\"" } @@ -381,7 +381,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["All"] + included_platforms = ["all"] } users { @@ -416,7 +416,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["All"] + included_platforms = ["all"] } users { @@ -458,7 +458,7 @@ resource "azuread_conditional_access_policy" "test" { } platforms { - included_platforms = ["All"] + included_platforms = ["all"] } users { diff --git a/internal/services/conditionalaccess/conditionalaccess.go b/internal/services/conditionalaccess/conditionalaccess.go index f96e95375a..5511a47b02 100644 --- a/internal/services/conditionalaccess/conditionalaccess.go +++ b/internal/services/conditionalaccess/conditionalaccess.go @@ -64,7 +64,7 @@ func flattenConditionalAccessDevices(in *msgraph.ConditionalAccessDevices) []int return []interface{}{ map[string]interface{}{ - "device_filter": flattenConditionalAccessDeviceFilter(in.DeviceFilter), + "filter": flattenConditionalAccessDeviceFilter(in.DeviceFilter), }, } } @@ -307,7 +307,7 @@ func expandConditionalAccessDevices(in []interface{}) *msgraph.ConditionalAccess config := in[0].(map[string]interface{}) - deviceFilter := config["device_filter"].([]interface{}) + deviceFilter := config["filter"].([]interface{}) if len(deviceFilter) > 0 { result.DeviceFilter = expandConditionalAccessFilter(deviceFilter) diff --git a/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go b/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go index cee03b8ac2..8456b5685e 100644 --- a/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go +++ b/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go @@ -224,7 +224,7 @@ const ( type ConditionalAccessDevicePlatform = string const ( - ConditionalAccessDevicePlatformAll ConditionalAccessDevicePlatform = "All" + ConditionalAccessDevicePlatformAll ConditionalAccessDevicePlatform = "all" ConditionalAccessDevicePlatformAndroid ConditionalAccessDevicePlatform = "android" ConditionalAccessDevicePlatformIos ConditionalAccessDevicePlatform = "iOS" ConditionalAccessDevicePlatformMacOs ConditionalAccessDevicePlatform = "macOS" diff --git a/vendor/modules.txt b/vendor/modules.txt index ab0f084245..68d449df4d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -203,7 +203,7 @@ github.com/klauspost/compress/fse github.com/klauspost/compress/huff0 github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash -# github.com/manicminer/hamilton v0.36.0 +# github.com/manicminer/hamilton v0.36.1 ## explicit github.com/manicminer/hamilton/auth github.com/manicminer/hamilton/environments