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

AUTH-5316 add conditional_access_enabled IDP, group #2654

Merged
merged 6 commits into from
Aug 23, 2023
Merged
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 .changelog/2654.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/cloudflare_access_group: add support for AccessGroupAzureAuthContext
```

```release-note:enhancement
resource/cloudflare_access_identity_provider: add conditional_access_enabled attr
```
33 changes: 33 additions & 0 deletions docs/resources/access_group.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ resource "cloudflare_access_group" "example" {
Optional:

- `any_valid_service_token` (Boolean)
- `auth_context` (Block List) (see [below for nested schema](#nestedblock--include--auth_context))
- `auth_method` (String)
- `azure` (Block List) (see [below for nested schema](#nestedblock--include--azure))
- `certificate` (Boolean)
Expand All @@ -106,6 +107,16 @@ Optional:
- `saml` (Block List) (see [below for nested schema](#nestedblock--include--saml))
- `service_token` (List of String)

<a id="nestedblock--include--auth_context"></a>
### Nested Schema for `include.auth_context`

Required:

- `ac_id` (String) The ACID of the Authentication Context.
- `id` (String) The ID of the Authentication Context.
- `identity_provider_id` (String) The ID of the Azure Identity provider.


<a id="nestedblock--include--azure"></a>
### Nested Schema for `include.azure`

Expand Down Expand Up @@ -169,6 +180,7 @@ Optional:
Optional:

- `any_valid_service_token` (Boolean)
- `auth_context` (Block List) (see [below for nested schema](#nestedblock--exclude--auth_context))
- `auth_method` (String)
- `azure` (Block List) (see [below for nested schema](#nestedblock--exclude--azure))
- `certificate` (Boolean)
Expand All @@ -189,6 +201,16 @@ Optional:
- `saml` (Block List) (see [below for nested schema](#nestedblock--exclude--saml))
- `service_token` (List of String)

<a id="nestedblock--exclude--auth_context"></a>
### Nested Schema for `exclude.auth_context`

Required:

- `ac_id` (String) The ACID of the Authentication Context.
- `id` (String) The ID of the Authentication Context.
- `identity_provider_id` (String) The ID of the Azure Identity provider.


<a id="nestedblock--exclude--azure"></a>
### Nested Schema for `exclude.azure`

Expand Down Expand Up @@ -252,6 +274,7 @@ Optional:
Optional:

- `any_valid_service_token` (Boolean)
- `auth_context` (Block List) (see [below for nested schema](#nestedblock--require--auth_context))
- `auth_method` (String)
- `azure` (Block List) (see [below for nested schema](#nestedblock--require--azure))
- `certificate` (Boolean)
Expand All @@ -272,6 +295,16 @@ Optional:
- `saml` (Block List) (see [below for nested schema](#nestedblock--require--saml))
- `service_token` (List of String)

<a id="nestedblock--require--auth_context"></a>
### Nested Schema for `require.auth_context`

Required:

- `ac_id` (String) The ACID of the Authentication Context.
- `id` (String) The ID of the Authentication Context.
- `identity_provider_id` (String) The ID of the Azure Identity provider.


<a id="nestedblock--require--azure"></a>
### Nested Schema for `require.azure`

Expand Down
1 change: 1 addition & 0 deletions docs/resources/access_identity_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Optional:
- `claims` (List of String)
- `client_id` (String)
- `client_secret` (String)
- `conditional_access_enabled` (Boolean)
- `directory_id` (String)
- `email_attribute_name` (String)
- `idp_public_cert` (String)
Expand Down
33 changes: 33 additions & 0 deletions docs/resources/access_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ resource "cloudflare_access_policy" "test_policy" {
Optional:

- `any_valid_service_token` (Boolean)
- `auth_context` (Block List) (see [below for nested schema](#nestedblock--include--auth_context))
- `auth_method` (String)
- `azure` (Block List) (see [below for nested schema](#nestedblock--include--azure))
- `certificate` (Boolean)
Expand All @@ -111,6 +112,16 @@ Optional:
- `saml` (Block List) (see [below for nested schema](#nestedblock--include--saml))
- `service_token` (List of String)

<a id="nestedblock--include--auth_context"></a>
### Nested Schema for `include.auth_context`

Required:

- `ac_id` (String) The ACID of the Authentication Context.
- `id` (String) The ID of the Authentication Context.
- `identity_provider_id` (String) The ID of the Azure Identity provider.


<a id="nestedblock--include--azure"></a>
### Nested Schema for `include.azure`

Expand Down Expand Up @@ -187,6 +198,7 @@ Optional:
Optional:

- `any_valid_service_token` (Boolean)
- `auth_context` (Block List) (see [below for nested schema](#nestedblock--exclude--auth_context))
- `auth_method` (String)
- `azure` (Block List) (see [below for nested schema](#nestedblock--exclude--azure))
- `certificate` (Boolean)
Expand All @@ -207,6 +219,16 @@ Optional:
- `saml` (Block List) (see [below for nested schema](#nestedblock--exclude--saml))
- `service_token` (List of String)

<a id="nestedblock--exclude--auth_context"></a>
### Nested Schema for `exclude.auth_context`

Required:

- `ac_id` (String) The ACID of the Authentication Context.
- `id` (String) The ID of the Authentication Context.
- `identity_provider_id` (String) The ID of the Azure Identity provider.


<a id="nestedblock--exclude--azure"></a>
### Nested Schema for `exclude.azure`

Expand Down Expand Up @@ -270,6 +292,7 @@ Optional:
Optional:

- `any_valid_service_token` (Boolean)
- `auth_context` (Block List) (see [below for nested schema](#nestedblock--require--auth_context))
- `auth_method` (String)
- `azure` (Block List) (see [below for nested schema](#nestedblock--require--azure))
- `certificate` (Boolean)
Expand All @@ -290,6 +313,16 @@ Optional:
- `saml` (Block List) (see [below for nested schema](#nestedblock--require--saml))
- `service_token` (List of String)

<a id="nestedblock--require--auth_context"></a>
### Nested Schema for `require.auth_context`

Required:

- `ac_id` (String) The ACID of the Authentication Context.
- `id` (String) The ID of the Authentication Context.
- `identity_provider_id` (String) The ID of the Azure Identity provider.


<a id="nestedblock--require--azure"></a>
### Nested Schema for `require.azure`

Expand Down
31 changes: 31 additions & 0 deletions internal/sdkv2provider/resource_cloudflare_access_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,19 @@ func BuildAccessGroupCondition(options map[string]interface{}) []interface{} {
KeysURL: eeCfg["keys_url"].(string),
}})
}
} else if accessGroupType == "auth_context" {
for _, v := range values.([]interface{}) {
ctxCfg := v.(map[string]interface{})
group = append(group, cloudflare.AccessGroupAzureAuthContext{AuthContext: struct {
ID string `json:"id"`
IdentityProviderID string `json:"identity_provider_id"`
ACID string `json:"ac_id"`
}{
ID: ctxCfg["id"].(string),
IdentityProviderID: ctxCfg["identity_provider_id"].(string),
ACID: ctxCfg["ac_id"].(string),
}})
}
} else {
for _, value := range values.([]interface{}) {
switch accessGroupType {
Expand Down Expand Up @@ -401,6 +414,9 @@ func TransformAccessGroupForSchema(ctx context.Context, accessGroup []interface{
externalEvaluationURL := ""
externalEvaluationKeysURL := ""
devicePostureRuleIDs := []string{}
authCtxID := ""
authCtxIDPID := ""
authCtxACID := ""

for _, group := range accessGroup {
for groupKey, groupValue := range group.(map[string]interface{}) {
Expand Down Expand Up @@ -501,6 +517,11 @@ func TransformAccessGroupForSchema(ctx context.Context, accessGroup []interface{
for _, dprID := range groupValue.(map[string]interface{}) {
devicePostureRuleIDs = append(devicePostureRuleIDs, dprID.(string))
}
case "auth_context":
ctxCfg := groupValue.(map[string]interface{})
authCtxIDPID = ctxCfg["identity_provider_id"].(string)
authCtxID = ctxCfg["id"].(string)
authCtxACID = ctxCfg["ac_id"].(string)
default:
tflog.Debug(ctx, fmt.Sprintf("Access Group key %q not transformed", groupKey))
}
Expand Down Expand Up @@ -602,6 +623,16 @@ func TransformAccessGroupForSchema(ctx context.Context, accessGroup []interface{
}
}

if authCtxID != "" && authCtxACID != "" && authCtxIDPID != "" {
groupMap["auth_context"] = []interface{}{
map[string]interface{}{
"id": authCtxID,
"ac_id": authCtxACID,
"identity_provider_id": authCtxIDPID,
},
}
}

if len(groups) > 0 {
groupMap["group"] = groups
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func TestAccCloudflareAccessGroup_FullConfig(t *testing.T) {
})
}

func TestAccCloudflareAccessGroupWithIDP(t *testing.T) {
func TestAccCloudflareAccessGroup_WithIDP(t *testing.T) {
rnd := generateRandomResourceName()
groupName := fmt.Sprintf("cloudflare_access_group.%s", rnd)
githubOrg := "Terraform-Cloudflare-Provider-Test-Org"
Expand Down Expand Up @@ -292,6 +292,35 @@ func TestAccCloudflareAccessGroupWithIDP(t *testing.T) {
})
}

func TestAccCloudflareAccessGroup_WithIDPAuthContext(t *testing.T) {
rnd := generateRandomResourceName()
groupName := fmt.Sprintf("cloudflare_access_group.%s", rnd)
ctxID := generateRandomResourceName()
ctxACID := "c1"

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAccount(t)
},
ProviderFactories: providerFactories,
CheckDestroy: testAccCheckCloudflareAccessGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccCloudflareAccessGroupWithIDPAuthContext(accountID, rnd, ctxID, ctxACID),
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudflareAccessGroupExists(groupName, cloudflare.AccountIdentifier(accountID), &accessGroup),
resource.TestCheckResourceAttr(groupName, consts.AccountIDSchemaKey, accountID),
resource.TestCheckResourceAttr(groupName, "name", rnd),
resource.TestCheckResourceAttrSet(groupName, "require.0.auth_context.0.identity_provider_id"),
resource.TestCheckResourceAttr(groupName, "require.0.auth_context.0.id", ctxID),
resource.TestCheckResourceAttr(groupName, "require.0.auth_context.0.ac_id", ctxACID),
),
},
},
})
}

func TestAccCloudflareAccessGroup_Updated(t *testing.T) {
var before, after cloudflare.AccessGroup
rnd := generateRandomResourceName()
Expand Down Expand Up @@ -492,6 +521,37 @@ resource "cloudflare_access_group" "%[2]s" {
}`, accountID, rnd, githubOrg, team)
}

func testAccCloudflareAccessGroupWithIDPAuthContext(accountID, rnd, authCtxID, authCtxACID string) string {
return fmt.Sprintf(`
resource "cloudflare_access_identity_provider" "%[2]s" {
account_id = "%[1]s"
name = "%[2]s"
type = "azureAD"
config {
client_id = "test"
client_secret = "secret"
directory_id = "foo"
}
}

resource "cloudflare_access_group" "%[2]s" {
account_id = "%[1]s"
name = "%[2]s"

include {
any_valid_service_token = true
}

require {
auth_context {
id = "%[3]s"
ac_id = "%[4]s"
identity_provider_id = cloudflare_access_identity_provider.%[2]s.id
}
}
}`, accountID, rnd, authCtxID, authCtxACID)
}

func testAccCheckCloudflareAccessGroupExists(n string, accessIdentifier *cloudflare.ResourceContainer, accessGroup *cloudflare.AccessGroup) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ func convertSchemaToStruct(d *schema.ResourceData) (cloudflare.AccessIdentityPro
IDPConfig.SupportGroups = d.Get("config.0.support_groups").(bool)
IDPConfig.TokenURL = d.Get("config.0.token_url").(string)
IDPConfig.PKCEEnabled = cloudflare.BoolPtr(d.Get("config.0.pkce_enabled").(bool))
IDPConfig.ConditionalAccessEnabled = d.Get("config.0.conditional_access_enabled").(bool)
}

return IDPConfig, nil
Expand Down Expand Up @@ -255,29 +256,30 @@ func convertStructToSchema(d *schema.ResourceData, options cloudflare.AccessIden
}

m := map[string]interface{}{
"api_token": options.APIToken,
"apps_domain": options.AppsDomain,
"attributes": attributes,
"auth_url": options.AuthURL,
"centrify_account": options.CentrifyAccount,
"centrify_app_id": options.CentrifyAppID,
"certs_url": options.CertsURL,
"client_id": options.ClientID,
"client_secret": options.ClientSecret,
"claims": options.Claims,
"scopes": options.Scopes,
"directory_id": options.DirectoryID,
"email_attribute_name": options.EmailAttributeName,
"idp_public_cert": options.IdpPublicCert,
"issuer_url": options.IssuerURL,
"okta_account": options.OktaAccount,
"onelogin_account": options.OneloginAccount,
"redirect_url": options.RedirectURL,
"sign_request": options.SignRequest,
"sso_target_url": options.SsoTargetURL,
"support_groups": options.SupportGroups,
"token_url": options.TokenURL,
"pkce_enabled": options.PKCEEnabled,
"api_token": options.APIToken,
"apps_domain": options.AppsDomain,
"attributes": attributes,
"auth_url": options.AuthURL,
"centrify_account": options.CentrifyAccount,
"centrify_app_id": options.CentrifyAppID,
"certs_url": options.CertsURL,
"client_id": options.ClientID,
"client_secret": options.ClientSecret,
"claims": options.Claims,
"scopes": options.Scopes,
"directory_id": options.DirectoryID,
"email_attribute_name": options.EmailAttributeName,
"idp_public_cert": options.IdpPublicCert,
"issuer_url": options.IssuerURL,
"okta_account": options.OktaAccount,
"onelogin_account": options.OneloginAccount,
"redirect_url": options.RedirectURL,
"sign_request": options.SignRequest,
"sso_target_url": options.SsoTargetURL,
"support_groups": options.SupportGroups,
"token_url": options.TokenURL,
"pkce_enabled": options.PKCEEnabled,
"conditional_access_enabled": options.ConditionalAccessEnabled,
}

return []interface{}{m}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ func TestAccCloudflareAccessIdentityProvider_SAML(t *testing.T) {
}

func TestAccCloudflareAccessIdentityProvider_AzureAD(t *testing.T) {
skipForDefaultAccount(t, "Pending investigation into automating Azure IDP.")

t.Parallel()
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
rnd := generateRandomResourceName()
Expand All @@ -209,6 +211,7 @@ func TestAccCloudflareAccessIdentityProvider_AzureAD(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "type", "azureAD"),
resource.TestCheckResourceAttr(resourceName, "config.0.client_id", "test"),
resource.TestCheckResourceAttr(resourceName, "config.0.directory_id", "directory"),
resource.TestCheckResourceAttr(resourceName, "config.0.condtional_access_enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "scim_config.0.enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "scim_config.0.user_deprovision", "true"),
resource.TestCheckResourceAttr(resourceName, "scim_config.0.seat_deprovision", "true"),
Expand Down Expand Up @@ -282,6 +285,7 @@ resource "cloudflare_access_identity_provider" "%[2]s" {
directory_id = "directory"
redirect_url = "https://terraform-cfapi.cloudflareaccess.com/cdn-cgi/access/callback"
support_groups = true
conditional_access_enabled = true
}
scim_config {
enabled = true
Expand Down
Loading
Loading