Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/resources/conditional_access_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ The following arguments are supported:
`conditions` block supports the following:

* `applications` - (Required) An `applications` block as documented below, which specifies applications and user actions included in and excluded from the policy.
* `authentication_flows` - (Optional) An `authentication_flows` block as documented below, which specifies transfer methods included in 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`.
* `client_applications` - (Optional) An `client_applications` block as documented below, which specifies service principals 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.
Expand All @@ -181,6 +182,12 @@ The following arguments are supported:

---

`authentication_flows` block supports the following:

* `transfer_methods` - One or more comma separated transfer methods included in the policy. Supported values are `authenticationTransfer` and `deviceCodeFlow`.

---

`client_applications` block supports the following:

* `excluded_service_principals` - (Optional) A list of service principal IDs explicitly excluded in the policy.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ func conditionalAccessPolicyResource() *pluginsdk.Resource {
},
},

"authentication_flows": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"transfer_methods": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(stable.PossibleValuesForConditionalAccessTransferMethods(), false),
},
},
},
},

"client_applications": {
Type: pluginsdk.TypeList,
Optional: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,25 @@ func TestAccConditionalAccessPolicy_insiderRisk(t *testing.T) {
})
}

func TestAccConditionalAccessPolicy_authenticationFlows(t *testing.T) {
data := acceptance.BuildTestData(t, "azuread_conditional_access_policy", "test")
r := ConditionalAccessPolicyResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.insiderRisk(data),
Check: acceptance.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"),
check.That(data.ResourceName).Key("conditions.0.authentication_flows.transfer_methods").HasValue("deviceCodeFlow"),
),
},
data.ImportStep(),
})
}

func (r ConditionalAccessPolicyResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := stable.ParseIdentityConditionalAccessPolicyID(state.ID)
if err != nil {
Expand Down Expand Up @@ -434,6 +453,10 @@ resource "azuread_conditional_access_policy" "test" {
excluded_applications = []
}

authentication_flows {
transfer_methods = "deviceCodeFlow"
}

devices {
filter {
mode = "exclude"
Expand Down Expand Up @@ -949,3 +972,36 @@ resource "azuread_conditional_access_policy" "test" {
}
`, data.RandomInteger)
}

func (ConditionalAccessPolicyResource) authenticationFlows(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azuread" {}

resource "azuread_conditional_access_policy" "test" {
display_name = "acctest-CONPOLICY-%[1]d"
state = "disabled"

conditions {
client_app_types = ["browser"]

authentication_flows {
transfer_methods = "deviceCodeFlow"
}

applications {
included_applications = ["None"]
}

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

grant_controls {
operator = "OR"
built_in_controls = ["block"]
}
}
`, data.RandomInteger)
}
35 changes: 35 additions & 0 deletions internal/services/conditionalaccess/conditionalaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func flattenConditionalAccessConditionSet(in *stable.ConditionalAccessConditionS
return []interface{}{
map[string]interface{}{
"applications": flattenConditionalAccessApplications(in.Applications),
"authentication_flows": flattenConditionalAccessAuthenticationFlows(in.AuthenticationFlows),
"client_applications": flattenConditionalAccessClientApplications(in.ClientApplications),
"users": flattenConditionalAccessUsers(in.Users),
"client_app_types": clientAppTypes,
Expand All @@ -69,6 +70,23 @@ func flattenConditionalAccessApplications(in stable.ConditionalAccessApplication
}
}

func flattenConditionalAccessAuthenticationFlows(in *stable.ConditionalAccessAuthenticationFlows) []interface{} {
if in == nil {
return []interface{}{}
}

transferMethods := ""
if in.TransferMethods != nil {
transferMethods = string(pointer.From(in.TransferMethods))
}

return []interface{}{
map[string]interface{}{
"transfer_methods": transferMethods,
},
}
}

func flattenConditionalAccessClientApplications(in *stable.ConditionalAccessClientApplications) []interface{} {
if in == nil {
return []interface{}{}
Expand Down Expand Up @@ -347,6 +365,7 @@ func expandConditionalAccessConditionSet(in []interface{}) *stable.ConditionalAc
config := in[0].(map[string]interface{})

applications := config["applications"].([]interface{})
authenticationFlows := config["authentication_flows"].([]interface{})
clientApplications := config["client_applications"].([]interface{})
devices := config["devices"].([]interface{})
locations := config["locations"].([]interface{})
Expand Down Expand Up @@ -378,6 +397,7 @@ func expandConditionalAccessConditionSet(in []interface{}) *stable.ConditionalAc
}

result.Applications = expandConditionalAccessApplications(applications)
result.AuthenticationFlows = expandConditionalAccessAuthenticationFlows(authenticationFlows)
result.ClientAppTypes = clientAppTypes
result.ClientApplications = expandConditionalAccessClientApplications(clientApplications)
result.Devices = expandConditionalAccessDevices(devices)
Expand Down Expand Up @@ -427,6 +447,21 @@ func expandConditionalAccessApplications(in []interface{}) stable.ConditionalAcc
return result
}

func expandConditionalAccessAuthenticationFlows(in []interface{}) *stable.ConditionalAccessAuthenticationFlows {
if len(in) == 0 || in[0] == nil {
return nil
}

result := stable.ConditionalAccessAuthenticationFlows{}
config := in[0].(map[string]interface{})

if transferMethods, ok := config["transfer_methods"]; ok && transferMethods.(string) != "" {
result.TransferMethods = pointer.To(stable.ConditionalAccessTransferMethods(transferMethods.(string)))
}

return &result
}

func expandConditionalAccessUsers(in []interface{}) *stable.ConditionalAccessUsers {
if len(in) == 0 || in[0] == nil {
return nil
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.