Skip to content

Commit

Permalink
AUTH-6146: Add Hybrid and Implicit support to Access OIDC SaaS Apps
Browse files Browse the repository at this point in the history
  • Loading branch information
ajholland committed May 23, 2024
1 parent 3f38356 commit 97db865
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .changelog/3324.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/cloudflare_access_application: Add Hybrid and Implicit flow support to OIDC SaaS Apps
```
Original file line number Diff line number Diff line change
Expand Up @@ -542,15 +542,19 @@ func TestAccCloudflareAccessApplication_WithOIDCSaas(t *testing.T) {
resource.TestCheckResourceAttr(name, "saas_app.0.auth_type", "oidc"),
resource.TestCheckResourceAttr(name, "saas_app.0.redirect_uris.#", "1"),
resource.TestCheckResourceAttr(name, "saas_app.0.redirect_uris.0", "https://saas-app.example/sso/oauth2/callback"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.#", "1"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.#", "2"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.0", "authorization_code"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.1", "hybrid"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.#", "4"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.0", "email"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.1", "groups"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.2", "openid"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.3", "profile"),
resource.TestCheckResourceAttr(name, "saas_app.0.app_launcher_url", "https://saas-app.example/sso/login"),
resource.TestCheckResourceAttr(name, "saas_app.0.group_filter_regex", ".*"),
resource.TestCheckResourceAttr(name, "saas_app.0.hybrid_and_implicit_options.#", "1"),
resource.TestCheckResourceAttr(name, "saas_app.0.hybrid_and_implicit_options.0.return_access_token_from_authorization_endpoint", "true"),
resource.TestCheckResourceAttr(name, "saas_app.0.hybrid_and_implicit_options.0.return_id_token_from_authorization_endpoint", "true"),
resource.TestCheckResourceAttrSet(name, "saas_app.0.client_secret"),
resource.TestCheckResourceAttrSet(name, "saas_app.0.public_key"),
),
Expand All @@ -574,15 +578,19 @@ func TestAccCloudflareAccessApplication_WithOIDCSaas_Import(t *testing.T) {
resource.TestCheckResourceAttr(name, "saas_app.0.auth_type", "oidc"),
resource.TestCheckResourceAttr(name, "saas_app.0.redirect_uris.#", "1"),
resource.TestCheckResourceAttr(name, "saas_app.0.redirect_uris.0", "https://saas-app.example/sso/oauth2/callback"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.#", "1"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.#", "2"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.0", "authorization_code"),
resource.TestCheckResourceAttr(name, "saas_app.0.grant_types.1", "hybrid"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.#", "4"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.0", "email"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.1", "groups"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.2", "openid"),
resource.TestCheckResourceAttr(name, "saas_app.0.scopes.3", "profile"),
resource.TestCheckResourceAttr(name, "saas_app.0.app_launcher_url", "https://saas-app.example/sso/login"),
resource.TestCheckResourceAttr(name, "saas_app.0.group_filter_regex", ".*"),
resource.TestCheckResourceAttr(name, "saas_app.0.hybrid_and_implicit_options.#", "1"),
resource.TestCheckResourceAttr(name, "saas_app.0.hybrid_and_implicit_options.0.return_access_token_from_authorization_endpoint", "true"),
resource.TestCheckResourceAttr(name, "saas_app.0.hybrid_and_implicit_options.0.return_id_token_from_authorization_endpoint", "true"),
)

resource.Test(t, resource.TestCase{
Expand Down Expand Up @@ -1090,10 +1098,14 @@ resource "cloudflare_access_application" "%[1]s" {
saas_app {
auth_type = "oidc"
redirect_uris = ["https://saas-app.example/sso/oauth2/callback"]
grant_types = ["authorization_code"]
grant_types = ["authorization_code", "hybrid"]
scopes = ["openid", "email", "profile", "groups"]
app_launcher_url = "https://saas-app.example/sso/login"
group_filter_regex = ".*"
hybrid_and_implicit_options {
return_id_token_from_authorization_endpoint = true
return_access_token_from_authorization_endpoint = true
}
}
auto_redirect_to_identity = false
}
Expand Down
44 changes: 44 additions & 0 deletions internal/sdkv2provider/schema_cloudflare_access_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,26 @@ func resourceCloudflareAccessApplicationSchema() map[string]*schema.Schema {
Optional: true,
Description: "A regex to filter Cloudflare groups returned in ID token and userinfo endpoint",
},
"hybrid_and_implicit_options": {
Type: schema.TypeList,
Optional: true,
Description: "Hybrid and Implicit Flow options",
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"return_access_token_from_authorization_endpoint": {
Type: schema.TypeBool,
Optional: true,
Description: "If true, the authorization endpoint will return an access token",
},
"return_id_token_from_authorization_endpoint": {
Type: schema.TypeBool,
Optional: true,
Description: "If true, the authorization endpoint will return an id token",
},
},
},
},

// SAML options
"sp_entity_id": {
Expand Down Expand Up @@ -758,6 +778,13 @@ func convertSaasSchemaToStruct(d *schema.ResourceData) *cloudflare.SaasApplicati
SaasConfig.GrantTypes = expandInterfaceToStringList(d.Get("saas_app.0.grant_types").(*schema.Set).List())
SaasConfig.Scopes = expandInterfaceToStringList(d.Get("saas_app.0.scopes").(*schema.Set).List())
SaasConfig.GroupFilterRegex = d.Get("saas_app.0.group_filter_regex").(string)

if _, ok := d.GetOk("saas_app.0.hybrid_and_implicit_options"); ok {
SaasConfig.HybridAndImplicitOptions = &cloudflare.AccessApplicationHybridAndImplicitOptions{

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / test

SaasConfig.HybridAndImplicitOptions undefined (type cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / test

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SaasConfig.HybridAndImplicitOptions undefined (type cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SaasConfig.HybridAndImplicitOptions undefined (type cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

SaasConfig.HybridAndImplicitOptions undefined (type cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 783 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

SaasConfig.HybridAndImplicitOptions undefined (type cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)
ReturnAccessTokenFromAuthorizationEndpoint: cloudflare.BoolPtr(d.Get("saas_app.0.hybrid_and_implicit_options.0.return_access_token_from_authorization_endpoint").(bool)),
ReturnIDTokenFromAuthorizationEndpoint: cloudflare.BoolPtr(d.Get("saas_app.0.hybrid_and_implicit_options.0.return_id_token_from_authorization_endpoint").(bool)),
}
}
} else {
SaasConfig.SPEntityID = d.Get("saas_app.0.sp_entity_id").(string)
SaasConfig.ConsumerServiceUrl = d.Get("saas_app.0.consumer_service_url").(string)
Expand Down Expand Up @@ -971,6 +998,18 @@ func convertSAMLAttributeStructToSchema(attr cloudflare.SAMLAttributeConfig) map
return m
}

func convertHybridAndImplicitOptionsStructToSchema(hybridAndImplicitOptions *cloudflare.AccessApplicationHybridAndImplicitOptions) []interface{} {

Check failure on line 1001 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / test

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 1001 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 1001 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 1001 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions

Check failure on line 1001 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

undefined: cloudflare.AccessApplicationHybridAndImplicitOptions
if hybridAndImplicitOptions == nil {
return []interface{}{}
}

m := map[string]interface{}{
"return_access_token_from_authorization_endpoint": hybridAndImplicitOptions.ReturnAccessTokenFromAuthorizationEndpoint,
"return_id_token_from_authorization_endpoint": hybridAndImplicitOptions.ReturnIDTokenFromAuthorizationEndpoint,
}
return []interface{}{m}
}

func convertSaasStructToSchema(d *schema.ResourceData, app *cloudflare.SaasApplication) []interface{} {
if app == nil {
return []interface{}{}
Expand All @@ -986,6 +1025,11 @@ func convertSaasStructToSchema(d *schema.ResourceData, app *cloudflare.SaasAppli
"group_filter_regex": app.GroupFilterRegex,
"app_launcher_url": app.AppLauncherURL,
}

if app.HybridAndImplicitOptions != nil {

Check failure on line 1029 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / test

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 1029 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 1029 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 1029 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)
m["hybrid_and_implicit_options"] = convertHybridAndImplicitOptionsStructToSchema(app.HybridAndImplicitOptions)

Check failure on line 1030 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / test

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 1030 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / golangci-lint

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 1030 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)

Check failure on line 1030 in internal/sdkv2provider/schema_cloudflare_access_application.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

app.HybridAndImplicitOptions undefined (type *cloudflare.SaasApplication has no field or method HybridAndImplicitOptions)
}

// client secret is only returned on create, if it is present in the state, preserve it
if client_secret, ok := d.GetOk("saas_app.0.client_secret"); ok {
m["client_secret"] = client_secret.(string)
Expand Down

0 comments on commit 97db865

Please sign in to comment.