From b14193819db9543ee5f05b83c3b4fe24e49362a9 Mon Sep 17 00:00:00 2001 From: Kyle Hiller Date: Tue, 10 Dec 2024 13:11:25 -0500 Subject: [PATCH] AUTH-6145 support multi-valued + service token authentication for SCIM provisioning to access applications --- .changelog/4743.txt | 3 + ...urce_cloudflare_access_application_test.go | 192 ++++-------------- .../schema_cloudflare_access_application.go | 151 ++++++++------ 3 files changed, 134 insertions(+), 212 deletions(-) create mode 100644 .changelog/4743.txt diff --git a/.changelog/4743.txt b/.changelog/4743.txt new file mode 100644 index 0000000000..5d6ea14b94 --- /dev/null +++ b/.changelog/4743.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/access_application: support multi-valued + Access service token authentication for SCIM provisioning to Access applications +``` diff --git a/internal/sdkv2provider/resource_cloudflare_access_application_test.go b/internal/sdkv2provider/resource_cloudflare_access_application_test.go index d220fe29e2..64b43713c6 100644 --- a/internal/sdkv2provider/resource_cloudflare_access_application_test.go +++ b/internal/sdkv2provider/resource_cloudflare_access_application_test.go @@ -255,8 +255,10 @@ func TestAccCloudflareAccessApplication_WithSCIMConfigInvalidMappingSchema(t *te }) } -func TestAccCloudflareAccessApplication_WithSCIMConfigHttpBasicMissingRequired(t *testing.T) { +func TestAccCloudflareAccessApplication_WithSCIMConfigOAuthBearerToken(t *testing.T) { rnd := generateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_access_application.%s", rnd) + idpName := fmt.Sprintf("cloudflare_zero_trust_access_identity_provider.%s", rnd) resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -266,14 +268,34 @@ func TestAccCloudflareAccessApplication_WithSCIMConfigHttpBasicMissingRequired(t CheckDestroy: testAccCheckCloudflareAccessApplicationDestroy, Steps: []resource.TestStep{ { - Config: testAccCloudflareAccessApplicationSCIMConfigHttpBasicMissingRequired(rnd, accountID, domain), - ExpectError: regexp.MustCompile(`.*all of\s*` + "`scim_config.0.authentication.0.password,scim_config.0.authentication.0.user`" + `\s*must be specified.*`), + Config: testAccCloudflareAccessApplicationSCIMConfigValidOAuthBearerToken(rnd, accountID, domain), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, consts.AccountIDSchemaKey, accountID), + resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "domain", fmt.Sprintf("%s.%s", rnd, domain)), + resource.TestCheckResourceAttr(name, "type", "self_hosted"), + resource.TestCheckResourceAttr(name, "session_duration", "24h"), + resource.TestCheckResourceAttr(name, "scim_config.#", "1"), + resource.TestCheckResourceAttr(name, "scim_config.0.enabled", "true"), + resource.TestCheckResourceAttr(name, "scim_config.0.remote_uri", "scim.com"), + resource.TestCheckResourceAttrPair(name, "scim_config.0.idp_uid", idpName, "id"), + resource.TestCheckResourceAttr(name, "scim_config.0.deactivate_on_delete", "true"), + resource.TestCheckResourceAttr(name, "scim_config.0.authentication.0.scheme", "oauthbearertoken"), + resource.TestCheckResourceAttrSet(name, "scim_config.0.authentication.0.token"), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.schema", "urn:ietf:params:scim:schemas:core:2.0:User"), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.enabled", "true"), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.filter", "title pr or userType eq \"Intern\""), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.transform_jsonata", "$merge([$, {'userName': $substringBefore($.userName, '@') & '+test@' & $substringAfter($.userName, '@')}])"), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.operations.0.create", "true"), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.operations.0.update", "true"), + resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.operations.0.delete", "true"), + ), }, }, }) } -func TestAccCloudflareAccessApplication_WithSCIMConfigOAuthBearerToken(t *testing.T) { +func TestAccCloudflareAccessApplication_WithSCIMConfigMultiAuth(t *testing.T) { rnd := generateRandomResourceName() name := fmt.Sprintf("cloudflare_zero_trust_access_application.%s", rnd) idpName := fmt.Sprintf("cloudflare_zero_trust_access_identity_provider.%s", rnd) @@ -286,7 +308,7 @@ func TestAccCloudflareAccessApplication_WithSCIMConfigOAuthBearerToken(t *testin CheckDestroy: testAccCheckCloudflareAccessApplicationDestroy, Steps: []resource.TestStep{ { - Config: testAccCloudflareAccessApplicationSCIMConfigValidOAuthBearerToken(rnd, accountID, domain), + Config: testAccCloudflareAccessApplicationSCIMConfigValidMulti(rnd, accountID, domain), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(name, consts.AccountIDSchemaKey, accountID), resource.TestCheckResourceAttr(name, "name", rnd), @@ -300,6 +322,9 @@ func TestAccCloudflareAccessApplication_WithSCIMConfigOAuthBearerToken(t *testin resource.TestCheckResourceAttr(name, "scim_config.0.deactivate_on_delete", "true"), resource.TestCheckResourceAttr(name, "scim_config.0.authentication.0.scheme", "oauthbearertoken"), resource.TestCheckResourceAttrSet(name, "scim_config.0.authentication.0.token"), + resource.TestCheckResourceAttr(name, "scim_config.0.authentication.1.scheme", "access_service_token"), + resource.TestCheckResourceAttr(name, "scim_config.0.authentication.1.client_id", "1234"), + resource.TestCheckResourceAttrSet(name, "scim_config.0.authentication.1.client_secret"), resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.schema", "urn:ietf:params:scim:schemas:core:2.0:User"), resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.enabled", "true"), resource.TestCheckResourceAttr(name, "scim_config.0.mappings.0.filter", "title pr or userType eq \"Intern\""), @@ -358,42 +383,6 @@ func TestAccCloudflareAccessApplication_WithSCIMConfigOAuth2(t *testing.T) { }) } -func TestAccCloudflareAccessApplication_WithSCIMConfigOAuth2MissingRequired(t *testing.T) { - rnd := generateRandomResourceName() - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckCloudflareAccessApplicationDestroy, - Steps: []resource.TestStep{ - { - Config: testAccCloudflareAccessApplicationSCIMConfigOAuth2MissingRequired(rnd, accountID, domain), - ExpectError: regexp.MustCompile(`.*all of\s*` + "`scim_config.0.authentication.0.authorization_url,scim_config.0.authentication.0.client_id,scim_config.0.authentication.0.client_secret,scim_config.0.authentication.0.token_url`" + `\s*must be specified.*`), - }, - }, - }) -} - -func TestAccCloudflareAccessApplication_WithSCIMConfigAuthenticationInvalid(t *testing.T) { - rnd := generateRandomResourceName() - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - }, - ProviderFactories: providerFactories, - CheckDestroy: testAccCheckCloudflareAccessApplicationDestroy, - Steps: []resource.TestStep{ - { - Config: testAccCloudflareAccessApplicationSCIMConfigAuthenticationInvalid(rnd, accountID, domain), - ExpectError: regexp.MustCompile(`Error: Conflicting configuration arguments`), - }, - }, - }) -} - func TestAccCloudflareAccessApplication_WithCORS(t *testing.T) { rnd := generateRandomResourceName() name := fmt.Sprintf("cloudflare_zero_trust_access_application.%s", rnd) @@ -1983,7 +1972,7 @@ resource "cloudflare_zero_trust_access_application" "%[1]s" { `, rnd, accountID, domain) } -func testAccCloudflareAccessApplicationSCIMConfigValidOAuth2(rnd, accountID, domain string) string { +func testAccCloudflareAccessApplicationSCIMConfigValidMulti(rnd, accountID, domain string) string { return fmt.Sprintf(` resource "cloudflare_zero_trust_access_identity_provider" "%[1]s" { account_id = "%[2]s" @@ -2015,66 +2004,13 @@ resource "cloudflare_zero_trust_access_application" "%[1]s" { idp_uid = cloudflare_zero_trust_access_identity_provider.%[1]s.id deactivate_on_delete = true authentication { - scheme = "oauth2" - client_id = "beepboop" - client_secret = "bop" - authorization_url = "https://www.authorization.com" - token_url = "https://www.token.com" - scopes = ["read"] - } - mappings { - schema = "urn:ietf:params:scim:schemas:core:2.0:User" - enabled = true - filter = "title pr or userType eq \"Intern\"" - transform_jsonata = "$merge([$, {'userName': $substringBefore($.userName, '@') & '+test@' & $substringAfter($.userName, '@')}])" - operations { - create = true - update = true - delete = true - } - } - } -} -`, rnd, accountID, domain) -} - -func testAccCloudflareAccessApplicationSCIMConfigOAuth2MissingRequired(rnd, accountID, domain string) string { - return fmt.Sprintf(` -resource "cloudflare_zero_trust_access_identity_provider" "%[1]s" { - account_id = "%[2]s" - name = "%[1]s" - type = "azureAD" - config { - client_id = "test" - client_secret = "test" - directory_id = "directory" - support_groups = true - } - scim_config { - enabled = true - group_member_deprovision = true - seat_deprovision = true - user_deprovision = true + scheme = "oauthbearertoken" + token = "beepboop" } -} - -resource "cloudflare_zero_trust_access_application" "%[1]s" { - account_id = "%[2]s" - name = "%[1]s" - type = "self_hosted" - session_duration = "24h" - domain = "%[1]s.%[3]s" - scim_config { - enabled = true - remote_uri = "scim.com" - idp_uid = cloudflare_zero_trust_access_identity_provider.%[1]s.id - deactivate_on_delete = true authentication { - scheme = "oauth2" - client_id = "beepboop" - client_secret = "bop" - authorization_url = "https://www.authorization.com" - scopes = ["read"] + scheme = "access_service_token" + client_id = "1234" + client_secret = "5678" } mappings { schema = "urn:ietf:params:scim:schemas:core:2.0:User" @@ -2086,13 +2022,14 @@ resource "cloudflare_zero_trust_access_application" "%[1]s" { update = true delete = true } + strictness = "strict" } } } `, rnd, accountID, domain) } -func testAccCloudflareAccessApplicationSCIMConfigAuthenticationInvalid(rnd, accountID, domain string) string { +func testAccCloudflareAccessApplicationSCIMConfigValidOAuth2(rnd, accountID, domain string) string { return fmt.Sprintf(` resource "cloudflare_zero_trust_access_identity_provider" "%[1]s" { account_id = "%[2]s" @@ -2129,9 +2066,6 @@ resource "cloudflare_zero_trust_access_application" "%[1]s" { client_secret = "bop" authorization_url = "https://www.authorization.com" token_url = "https://www.token.com" - token = "1234" - user = "user" - password = "ahhh" scopes = ["read"] } mappings { @@ -2150,56 +2084,6 @@ resource "cloudflare_zero_trust_access_application" "%[1]s" { `, rnd, accountID, domain) } -func testAccCloudflareAccessApplicationSCIMConfigHttpBasicMissingRequired(rnd, accountID, domain string) string { - return fmt.Sprintf(` -resource "cloudflare_zero_trust_access_identity_provider" "%[1]s" { - account_id = "%[2]s" - name = "%[1]s" - type = "azureAD" - config { - client_id = "test" - client_secret = "test" - directory_id = "directory" - support_groups = true - } - scim_config { - enabled = true - group_member_deprovision = true - seat_deprovision = true - user_deprovision = true - } -} - -resource "cloudflare_zero_trust_access_application" "%[1]s" { - account_id = "%[2]s" - name = "%[1]s" - type = "self_hosted" - session_duration = "24h" - domain = "%[1]s.%[3]s" - scim_config { - enabled = true - remote_uri = "scim.com" - idp_uid = cloudflare_zero_trust_access_identity_provider.%[1]s.id - deactivate_on_delete = true - authentication { - scheme = "httpbasic" - user = "test" - } - mappings { - schema = "urn:ietf:params:scim:schemas:core:2.0:User" - enabled = true - filter = "title pr or userType eq \"Intern\"" - transform_jsonata = "$merge([$, {'userName': $substringBefore($.userName, '@') & '+test@' & $substringAfter($.userName, '@')}])" - operations { - create = true - update = true - delete = true - } - } - } -}`, rnd, accountID, domain) -} - func testAccCloudflareAccessApplicationSCIMConfigInvalidMappingSchema(rnd, accountID, domain string) string { return fmt.Sprintf(` resource "cloudflare_zero_trust_access_identity_provider" "%[1]s" { diff --git a/internal/sdkv2provider/schema_cloudflare_access_application.go b/internal/sdkv2provider/schema_cloudflare_access_application.go index e5e8967b8d..684e7ffa76 100644 --- a/internal/sdkv2provider/schema_cloudflare_access_application.go +++ b/internal/sdkv2provider/schema_cloudflare_access_application.go @@ -706,80 +706,65 @@ func resourceCloudflareAccessApplicationSchema() map[string]*schema.Schema { Type: schema.TypeList, Optional: true, Description: "Attributes for configuring HTTP Basic, OAuth Bearer token, or OAuth 2 authentication schemes for SCIM provisioning to an application.", - MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ // Common Attributes "scheme": { Type: schema.TypeString, Required: true, - ValidateFunc: validation.StringInSlice([]string{"httpbasic", "oauthbearertoken", "oauth2"}, false), + ValidateFunc: validation.StringInSlice([]string{"httpbasic", "oauthbearertoken", "oauth2", "access_service_token"}, false), Description: "The authentication scheme to use when making SCIM requests to this application.", }, // HTTP Basic Authentication Attributes "user": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"scim_config.0.authentication.0.password"}, - ConflictsWith: []string{"scim_config.0.authentication.0.token", "scim_config.0.authentication.0.client_id", "scim_config.0.authentication.0.client_secret", "scim_config.0.authentication.0.authorization_url", "scim_config.0.authentication.0.token_url", "scim_config.0.authentication.0.scopes"}, - Description: "User name used to authenticate with the remote SCIM service.", + Type: schema.TypeString, + Optional: true, + Description: "User name used to authenticate with the remote SCIM service.", }, "password": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"scim_config.0.authentication.0.user"}, - ConflictsWith: []string{"scim_config.0.authentication.0.token", "scim_config.0.authentication.0.client_id", "scim_config.0.authentication.0.client_secret", "scim_config.0.authentication.0.authorization_url", "scim_config.0.authentication.0.token_url", "scim_config.0.authentication.0.scopes"}, + Type: schema.TypeString, + Optional: true, StateFunc: func(val interface{}) string { return CONCEALED_STRING }, }, // OAuth Bearer Token Authentication Attributes "token": { - Type: schema.TypeString, - Optional: true, - Description: "Token used to authenticate with the remote SCIM service.", - ConflictsWith: []string{"scim_config.0.authentication.0.user", "scim_config.0.authentication.0.password", "scim_config.0.authentication.0.client_id", "scim_config.0.authentication.0.client_secret", "scim_config.0.authentication.0.authorization_url", "scim_config.0.authentication.0.token_url", "scim_config.0.authentication.0.scopes"}, + Type: schema.TypeString, + Optional: true, + Description: "Token used to authenticate with the remote SCIM service.", StateFunc: func(val interface{}) string { return CONCEALED_STRING }, }, // OAuth 2 Authentication Attributes "client_id": { - Type: schema.TypeString, - Optional: true, - Description: "Client ID used to authenticate when generating a token for authenticating with the remote SCIM service.", - RequiredWith: []string{"scim_config.0.authentication.0.client_secret", "scim_config.0.authentication.0.authorization_url", "scim_config.0.authentication.0.token_url"}, - ConflictsWith: []string{"scim_config.0.authentication.0.user", "scim_config.0.authentication.0.password", "scim_config.0.authentication.0.token"}, + Type: schema.TypeString, + Optional: true, + Description: "Client ID used to authenticate when generating a token for authenticating with the remote SCIM service.", }, "client_secret": { - Type: schema.TypeString, - Optional: true, - Description: "Secret used to authenticate when generating a token for authenticating with the remove SCIM service.", - RequiredWith: []string{"scim_config.0.authentication.0.client_id", "scim_config.0.authentication.0.authorization_url", "scim_config.0.authentication.0.token_url"}, - ConflictsWith: []string{"scim_config.0.authentication.0.user", "scim_config.0.authentication.0.password", "scim_config.0.authentication.0.token"}, + Type: schema.TypeString, + Optional: true, + Description: "Secret used to authenticate when generating a token for authenticating with the remove SCIM service.", StateFunc: func(val interface{}) string { return CONCEALED_STRING }, }, "authorization_url": { - Type: schema.TypeString, - Optional: true, - Description: "URL used to generate the auth code used during token generation.", - RequiredWith: []string{"scim_config.0.authentication.0.client_secret", "scim_config.0.authentication.0.client_id", "scim_config.0.authentication.0.token_url"}, - ConflictsWith: []string{"scim_config.0.authentication.0.user", "scim_config.0.authentication.0.password", "scim_config.0.authentication.0.token"}, + Type: schema.TypeString, + Optional: true, + Description: "URL used to generate the auth code used during token generation.", }, "token_url": { - Type: schema.TypeString, - Optional: true, - Description: "URL used to generate the token used to authenticate with the remote SCIM service.", - RequiredWith: []string{"scim_config.0.authentication.0.client_secret", "scim_config.0.authentication.0.authorization_url", "scim_config.0.authentication.0.client_id"}, - ConflictsWith: []string{"scim_config.0.authentication.0.user", "scim_config.0.authentication.0.password", "scim_config.0.authentication.0.token"}, + Type: schema.TypeString, + Optional: true, + Description: "URL used to generate the token used to authenticate with the remote SCIM service.", }, "scopes": { - Type: schema.TypeSet, - Description: "The authorization scopes to request when generating the token used to authenticate with the remove SCIM service.", - Optional: true, - ConflictsWith: []string{"scim_config.0.authentication.0.user", "scim_config.0.authentication.0.password", "scim_config.0.authentication.0.token"}, + Type: schema.TypeSet, + Description: "The authorization scopes to request when generating the token used to authenticate with the remove SCIM service.", + Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -1210,37 +1195,48 @@ func convertScimConfigMappingsSchemaToStruct(mappingData map[string]interface{}) func convertScimConfigAuthenticationSchemaToStruct(d *schema.ResourceData) *cloudflare.AccessApplicationScimAuthenticationJson { auth := new(cloudflare.AccessApplicationScimAuthenticationJson) - - if _, ok := d.GetOk("scim_config.0.authentication"); ok { - scheme := cloudflare.AccessApplicationScimAuthenticationScheme(d.Get("scim_config.0.authentication.0.scheme").(string)) + multi := new(cloudflare.AccessApplicationMultipleScimAuthentication) + auth.Value = multi + + keyFmt := "scim_config.0.authentication.%d" + i := 0 + for _, ok := d.GetOk(fmt.Sprintf(keyFmt, i)); ok; _, ok = d.GetOk(fmt.Sprintf(keyFmt, i)) { + key := fmt.Sprintf(keyFmt, i) + scheme := cloudflare.AccessApplicationScimAuthenticationScheme(d.Get(key + ".scheme").(string)) switch scheme { case cloudflare.AccessApplicationScimAuthenticationSchemeHttpBasic: base := &cloudflare.AccessApplicationScimAuthenticationHttpBasic{ - User: d.Get("scim_config.0.authentication.0.user").(string), - Password: d.Get("scim_config.0.authentication.0.password").(string), + User: d.Get(key + ".user").(string), + Password: d.Get(key + ".password").(string), } base.Scheme = scheme - auth.Value = base - break + *multi = append(*multi, &cloudflare.AccessApplicationScimAuthenticationSingleJSON{Value: base}) case cloudflare.AccessApplicationScimAuthenticationSchemeOauthBearerToken: base := &cloudflare.AccessApplicationScimAuthenticationOauthBearerToken{ - Token: d.Get("scim_config.0.authentication.0.token").(string), + Token: d.Get(key + ".token").(string), } base.Scheme = scheme - auth.Value = base - break + *multi = append(*multi, &cloudflare.AccessApplicationScimAuthenticationSingleJSON{Value: base}) case cloudflare.AccessApplicationScimAuthenticationSchemeOauth2: base := &cloudflare.AccessApplicationScimAuthenticationOauth2{ - ClientID: d.Get("scim_config.0.authentication.0.client_id").(string), - ClientSecret: d.Get("scim_config.0.authentication.0.client_secret").(string), - AuthorizationURL: d.Get("scim_config.0.authentication.0.authorization_url").(string), - TokenURL: d.Get("scim_config.0.authentication.0.token_url").(string), - Scopes: expandInterfaceToStringList(d.Get("scim_config.0.authentication.0.scopes").(*schema.Set).List()), + ClientID: d.Get(key + ".client_id").(string), + ClientSecret: d.Get(key + ".client_secret").(string), + AuthorizationURL: d.Get(key + ".authorization_url").(string), + TokenURL: d.Get(key + ".token_url").(string), + Scopes: expandInterfaceToStringList(d.Get(key + ".scopes").(*schema.Set).List()), + } + base.Scheme = scheme + *multi = append(*multi, &cloudflare.AccessApplicationScimAuthenticationSingleJSON{Value: base}) + case cloudflare.AccessApplicationScimAuthenticationAccessServiceToken: + base := &cloudflare.AccessApplicationScimAuthenticationServiceToken{ + ClientID: d.Get(key + ".client_id").(string), + ClientSecret: d.Get(key + ".client_secret").(string), } base.Scheme = scheme - auth.Value = base - break + *multi = append(*multi, &cloudflare.AccessApplicationScimAuthenticationSingleJSON{Value: base}) } + + i++ } return auth @@ -1445,12 +1441,13 @@ func convertScimConfigStructToSchema(scimConfig *cloudflare.AccessApplicationSCI return []interface{}{} } + auth := convertScimConfigAuthenticationStructToSchema(scimConfig.Authentication) config := map[string]interface{}{ "enabled": scimConfig.Enabled, "remote_uri": scimConfig.RemoteURI, "idp_uid": scimConfig.IdPUID, "deactivate_on_delete": cloudflare.Bool(scimConfig.DeactivateOnDelete), - "authentication": convertScimConfigAuthenticationStructToSchema(scimConfig.Authentication), + "authentication": auth, "mappings": convertScimConfigMappingsStructsToSchema(scimConfig.Mappings), } @@ -1464,11 +1461,17 @@ func convertScimConfigAuthenticationStructToSchema(scimAuth *cloudflare.AccessAp auth := map[string]interface{}{} switch t := scimAuth.Value.(type) { + case *cloudflare.AccessApplicationMultipleScimAuthentication: + vals := []interface{}{} + for _, authn := range *t { + vals = append(vals, convertScimConfigSingleAuthentiationToSchema(&cloudflare.AccessApplicationScimAuthenticationJson{Value: authn.Value})) + } + + return vals case *cloudflare.AccessApplicationScimAuthenticationHttpBasic: auth["scheme"] = t.Scheme auth["user"] = t.User auth["password"] = t.Password - case *cloudflare.AccessApplicationScimAuthenticationOauthBearerToken: auth["scheme"] = t.Scheme auth["token"] = t.Token @@ -1479,11 +1482,43 @@ func convertScimConfigAuthenticationStructToSchema(scimAuth *cloudflare.AccessAp auth["authorization_url"] = t.AuthorizationURL auth["token_url"] = t.TokenURL auth["scopes"] = t.Scopes + case *cloudflare.AccessApplicationScimAuthenticationServiceToken: + auth["scheme"] = t.Scheme + auth["client_id"] = t.ClientID + auth["client_secret"] = t.ClientSecret } return []interface{}{auth} } +func convertScimConfigSingleAuthentiationToSchema(scimAuth *cloudflare.AccessApplicationScimAuthenticationJson) interface{} { + auth := map[string]interface{}{} + + switch t := scimAuth.Value.(type) { + case *cloudflare.AccessApplicationScimAuthenticationHttpBasic: + auth["scheme"] = t.Scheme + auth["user"] = t.User + auth["password"] = t.Password + + case *cloudflare.AccessApplicationScimAuthenticationOauthBearerToken: + auth["scheme"] = t.Scheme + auth["token"] = t.Token + case *cloudflare.AccessApplicationScimAuthenticationOauth2: + auth["scheme"] = t.Scheme + auth["client_id"] = t.ClientID + auth["client_secret"] = t.ClientSecret + auth["authorization_url"] = t.AuthorizationURL + auth["token_url"] = t.TokenURL + auth["scopes"] = t.Scopes + case *cloudflare.AccessApplicationScimAuthenticationServiceToken: + auth["scheme"] = t.Scheme + auth["client_id"] = t.ClientID + auth["client_secret"] = t.ClientSecret + } + + return auth +} + func convertScimConfigMappingsStructsToSchema(mappingsData []*cloudflare.AccessApplicationScimMapping) []interface{} { mappings := []interface{}{}