Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional access policy - support persistent browser session control #677

1 change: 1 addition & 0 deletions docs/resources/conditional_access_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ The following arguments are supported:
-> Only Office 365, Exchange Online and Sharepoint Online support application enforced restrictions.

* `cloud_app_security_policy` - (Optional) Enables cloud app security and specifies the cloud app security policy to use. Possible values are: `blockDownloads`, `mcasConfigured`, `monitorOnly` or `unknownFutureValue`.
* `persistent_browser_mode` - (Optional) Session control to define whether to persist cookies or not. Possible values are: `always` or `never`.
* `sign_in_frequency` - (Optional) Number of days or hours to enforce sign-in frequency. Required when `sign_in_frequency_period` is specified. Due to an API issue, removing this property forces a new resource to be created.
* `sign_in_frequency_period` - (Optional) The time period to enforce sign-in frequency. Possible values are: `hours` or `days`. Required when `sign_in_frequency_period` is specified. Due to an API issue, removing this property forces a new resource to be created.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,15 @@ func conditionalAccessPolicyResource() *schema.Resource {
}, false),
},

"persistent_browser_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
msgraph.PersistentBrowserSessionModeAlways,
msgraph.PersistentBrowserSessionModeNever,
}, false),
},
Comment on lines +400 to +407
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be a boolean so could become a bool? maybe

Suggested change
"persistent_browser_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
msgraph.PersistentBrowserSessionModeAlways,
msgraph.PersistentBrowserSessionModeNever,
}, false),
},
"persistent_browser_cookies_enabled": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
msgraph.PersistentBrowserSessionModeAlways,
msgraph.PersistentBrowserSessionModeNever,
}, false),
},

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more of a triple-value setting (there's an underlying bool which we infer the value of) so we'll probably have to stick with enum-like strings


"sign_in_frequency": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -444,8 +453,21 @@ func conditionalAccessPolicyDiffSuppress(k, old, new string, d *schema.ResourceD
sessionControlsRaw := d.Get("session_controls").([]interface{})
if len(sessionControlsRaw) == 1 {
sessionControls := sessionControlsRaw[0].(map[string]interface{})
if v, ok := sessionControls["application_enforced_restrictions_enabled"]; ok && !v.(bool) {
suppress = true
suppress = true
if v, ok := sessionControls["application_enforced_restrictions_enabled"]; ok && v.(bool) {
suppress = false
}
if v, ok := sessionControls["cloud_app_security_policy"]; ok && v.(string) != "" {
suppress = false
}
if v, ok := sessionControls["persistent_browser_mode"]; ok && v.(string) != "" {
suppress = false
}
if v, ok := sessionControls["sign_in_frequency"]; ok && v.(int) > 0 {
suppress = false
}
if v, ok := sessionControls["sign_in_frequency_period"]; ok && v.(string) != "" {
suppress = false
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,26 @@ func TestAccConditionalAccessPolicy_sessionControls(t *testing.T) {
),
},
data.ImportStep(),
{
Config: r.sessionControlsUpdate(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.sessionControls(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.basic(data),
Check: resource.ComposeTestCheckFunc(
Expand Down Expand Up @@ -433,13 +453,57 @@ resource "azuread_conditional_access_policy" "test" {
session_controls {
application_enforced_restrictions_enabled = true
cloud_app_security_policy = "monitorOnly"
persistent_browser_mode = "never"
sign_in_frequency = 10
sign_in_frequency_period = "hours"
}
}
`, data.RandomInteger)
}

func (ConditionalAccessPolicyResource) sessionControlsUpdate(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"]
}

locations {
included_locations = ["All"]
}

platforms {
included_platforms = ["all"]
}

users {
included_users = ["All"]
excluded_users = ["GuestsOrExternalUsers"]
}
}

grant_controls {
operator = "OR"
built_in_controls = ["block"]
}

session_controls {
application_enforced_restrictions_enabled = true
cloud_app_security_policy = "blockDownloads"
persistent_browser_mode = "always"
sign_in_frequency = 2
sign_in_frequency_period = "days"
}
}
`, data.RandomInteger)
}

func (ConditionalAccessPolicyResource) sessionControlsDisabled(data acceptance.TestData) string {
return fmt.Sprintf(`
resource "azuread_conditional_access_policy" "test" {
Expand Down
13 changes: 13 additions & 0 deletions internal/services/conditionalaccess/conditionalaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,16 @@ func flattenConditionalAccessSessionControls(in *msgraph.ConditionalAccessSessio
signInFrequencyPeriod = *in.SignInFrequency.Type
}

persistentBrowserMode := ""
if in.PersistentBrowser != nil && in.PersistentBrowser.Mode != nil {
persistentBrowserMode = *in.PersistentBrowser.Mode
}

return []interface{}{
map[string]interface{}{
"application_enforced_restrictions_enabled": applicationEnforceRestrictions,
"cloud_app_security_policy": cloudAppSecurity,
"persistent_browser_mode": persistentBrowserMode,
"sign_in_frequency": signInFrequency,
"sign_in_frequency_period": signInFrequencyPeriod,
},
Expand Down Expand Up @@ -374,6 +380,13 @@ func expandConditionalAccessSessionControls(in []interface{}) *msgraph.Condition
}
}

if persistentBrowserMode := config["persistent_browser_mode"].(string); persistentBrowserMode != "" {
result.PersistentBrowser = &msgraph.PersistentBrowserSessionControl{
IsEnabled: utils.Bool(true),
Mode: utils.String(persistentBrowserMode),
}
}

if signInFrequency := config["sign_in_frequency"].(int); signInFrequency > 0 {
result.SignInFrequency = &msgraph.SignInFrequencySessionControl{
IsEnabled: utils.Bool(true),
Expand Down