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

azuread_conditional_access_policy: support includeAuthenticationContextClassReferences and applicationFilter of conditions #1534

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
13 changes: 11 additions & 2 deletions docs/resources/conditional_access_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,17 @@ The following arguments are supported:
`applications` block supports the following:

* `excluded_applications` - (Optional) A list of application IDs explicitly excluded from the policy. Can also be set to `Office365`.
* `included_applications` - (Optional) A list of application IDs the policy applies to, unless explicitly excluded (in `excluded_applications`). Can also be set to `All`, `None` or `Office365`. Cannot be specified with `included_user_actions`. One of `included_applications` or `included_user_actions` must be specified.
* `included_user_actions` - (Optional) A list of user actions to include. Supported values are `urn:user:registerdevice` and `urn:user:registersecurityinfo`. Cannot be specified with `included_applications`. One of `included_applications` or `included_user_actions` must be specified.
* `filter` - (Optional) A `filter` block as described below.
* `included_applications` - (Optional) A list of application IDs the policy applies to, unless explicitly excluded (in `excluded_applications`). Can also be set to `All`, `None` or `Office365`. Cannot be specified with `included_user_actions`. One of `included_applications`, `included_user_actions` or `included_authentication_context_class_references` must be specified.
* `included_authentication_context_class_references` - (Optional) A list of authentication context class reference to include. Supported values are `c1` through `c99`.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see in the API docs that it only supports IDs up to c25,
In fact, the official doc states that IDs can be used up to c99.

* `included_user_actions` - (Optional) A list of user actions to include. Supported values are `urn:user:registerdevice` and `urn:user:registersecurityinfo`. Cannot be specified with `included_applications`. One of `included_applications`, `included_user_actions` or `included_authentication_context_class_references` must be specified.

---

`filter` block supports the following:

* `mode` - (Required) Whether to include in, or exclude from, matching applications from the policy. Supported values are `include` or `exclude`.
* `rule` - (Required) Condition filter to match applications. For more information, see [official documentation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-filter-for-applications).

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"log"
"regexp"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
Expand Down Expand Up @@ -86,7 +87,7 @@ func conditionalAccessPolicyResource() *pluginsdk.Resource {
"included_applications": {
Type: pluginsdk.TypeList,
Optional: true,
ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions"},
ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions", "conditions.0.applications.0.included_authentication_context_class_references"},
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateFunc: validation.StringIsNotEmpty,
Expand All @@ -102,15 +103,45 @@ func conditionalAccessPolicyResource() *pluginsdk.Resource {
},
},

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

"rule": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
},

"included_user_actions": {
Type: pluginsdk.TypeList,
Optional: true,
ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions"},
ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions", "conditions.0.applications.0.included_authentication_context_class_references"},
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateFunc: validation.StringIsNotEmpty,
},
},

"included_authentication_context_class_references": {
Type: pluginsdk.TypeList,
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateFunc: validation.StringMatch(regexp.MustCompile("^c([1-9]|[1-9][0-9])$"), ""),
},
},
},
},
},
Expand Down
12 changes: 10 additions & 2 deletions internal/services/conditionalaccess/conditionalaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ func flattenConditionalAccessApplications(in stable.ConditionalAccessApplication
map[string]interface{}{
"included_applications": tf.FlattenStringSlicePtr(in.IncludeApplications),
"excluded_applications": tf.FlattenStringSlicePtr(in.ExcludeApplications),
"filter": flattenConditionalAccessFilter(in.ApplicationFilter),
"included_user_actions": tf.FlattenStringSlicePtr(in.IncludeUserActions),
"included_authentication_context_class_references": tf.FlattenStringSlicePtr(in.IncludeAuthenticationContextClassReferences),
},
}
}
Expand Down Expand Up @@ -102,7 +104,7 @@ func flattenConditionalAccessDevices(in *stable.ConditionalAccessDevices) []inte

return []interface{}{
map[string]interface{}{
"filter": flattenConditionalAccessDeviceFilter(in.DeviceFilter),
"filter": flattenConditionalAccessFilter(in.DeviceFilter),
},
}
}
Expand Down Expand Up @@ -222,7 +224,7 @@ func flattenConditionalAccessSessionControls(in *stable.ConditionalAccessSession
}
}

func flattenConditionalAccessDeviceFilter(in *stable.ConditionalAccessFilter) []interface{} {
func flattenConditionalAccessFilter(in *stable.ConditionalAccessFilter) []interface{} {
if in == nil {
return []interface{}{}
}
Expand Down Expand Up @@ -398,11 +400,17 @@ func expandConditionalAccessApplications(in []interface{}) stable.ConditionalAcc

includeApplications := config["included_applications"].([]interface{})
excludeApplications := config["excluded_applications"].([]interface{})
applicationilter := config["filter"].([]interface{})
includeUserActions := config["included_user_actions"].([]interface{})
includeAuthenticationContextClassReferences := config["included_authentication_context_class_references"].([]interface{})

result.IncludeApplications = tf.ExpandStringSlicePtr(includeApplications)
result.ExcludeApplications = tf.ExpandStringSlicePtr(excludeApplications)
if len(applicationilter) > 0 {
result.ApplicationFilter = expandConditionalAccessFilter(applicationilter)
}
result.IncludeUserActions = tf.ExpandStringSlicePtr(includeUserActions)
result.IncludeAuthenticationContextClassReferences = tf.ExpandStringSlicePtr(includeAuthenticationContextClassReferences)

return result
}
Expand Down
Loading