Skip to content

Commit

Permalink
DXCDT-256: Add support for okta connections (#395)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiught authored Nov 7, 2022
1 parent 7dc9126 commit 87f4fda
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 4 deletions.
33 changes: 33 additions & 0 deletions docs/resources/connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,39 @@ resource "auth0_connection" "oidc" {
}
```

### Okta Connection

```terraform
# This is an example of an Okta Workforce connection.
resource "auth0_connection" "okta" {
name = "okta-connection"
display_name = "Okta Workforce Connection"
strategy = "okta"
show_as_button = false
options {
client_id = "1234567"
client_secret = "1234567"
domain = "example.okta.com"
domain_aliases = ["example.com"]
issuer = "https://example.okta.com"
jwks_uri = "https://example.okta.com/v1/oauth2/certs"
token_endpoint = "https://example.okta.com/v1/oauth2/token"
userinfo_endpoint = "https://example.okta.com/v1/oauth2/token/userinfo"
authorization_endpoint = "https://example.okta.com/signin/authorize"
scopes = ["openid", "email"]
set_user_root_attributes = "on_first_login"
non_persistent_attrs = ["ethnicity", "gender"]
upstream_params = jsonencode({
"screen_name" : {
"alias" : "login_hint"
}
})
}
}
```

<!-- schema generated by tfplugindocs -->
## Schema

Expand Down
28 changes: 28 additions & 0 deletions examples/resources/auth0_connection/resource_with_okta.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This is an example of an Okta Workforce connection.

resource "auth0_connection" "okta" {
name = "okta-connection"
display_name = "Okta Workforce Connection"
strategy = "okta"
show_as_button = false

options {
client_id = "1234567"
client_secret = "1234567"
domain = "example.okta.com"
domain_aliases = ["example.com"]
issuer = "https://example.okta.com"
jwks_uri = "https://example.okta.com/v1/oauth2/certs"
token_endpoint = "https://example.okta.com/v1/oauth2/token"
userinfo_endpoint = "https://example.okta.com/v1/oauth2/token/userinfo"
authorization_endpoint = "https://example.okta.com/signin/authorize"
scopes = ["openid", "email"]
set_user_root_attributes = "on_first_login"
non_persistent_attrs = ["ethnicity", "gender"]
upstream_params = jsonencode({
"screen_name" : {
"alias" : "login_hint"
}
})
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/auth0/terraform-provider-auth0
go 1.19

require (
github.com/auth0/go-auth0 v0.12.0
github.com/auth0/go-auth0 v0.13.0
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/terraform-plugin-docs v0.13.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/auth0/go-auth0 v0.12.0 h1:ssMGNrK3Nq9s8kduBRyZX7vCXKp5VckFjY4v2G7EBjs=
github.com/auth0/go-auth0 v0.12.0/go.mod h1:XtmeQ7vZzyss3AAaLXMpupn28Y1Xj/DCt1IGEJRZ2gY=
github.com/auth0/go-auth0 v0.13.0 h1:0HHEHwfZnpb3xmZOkZEHeqwJ85k3yTN2wCNJobNvLh4=
github.com/auth0/go-auth0 v0.13.0/go.mod h1:FOHI93YSRdyWcgecep+6YFNZ0v0FsAaMbnSVzTWdMHI=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
Expand Down
2 changes: 1 addition & 1 deletion internal/provider/resource_auth0_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var connectionSchema = map[string]*schema.Schema{
"evernote-sandbox", "evernote", "exact", "facebook",
"fitbit", "flickr", "github", "google-apps",
"google-oauth2", "guardian", "instagram", "ip", "linkedin",
"miicard", "oauth1", "oauth2", "office365", "oidc", "paypal",
"miicard", "oauth1", "oauth2", "office365", "oidc", "okta", "paypal",
"paypal-sandbox", "pingfederate", "planningcenter",
"renren", "salesforce-community", "salesforce-sandbox",
"salesforce", "samlp", "sharepoint", "shopify", "sms",
Expand Down
110 changes: 110 additions & 0 deletions internal/provider/resource_auth0_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,116 @@ resource "auth0_connection" "oidc" {
}
`

func TestAccConnectionOkta(t *testing.T) {
httpRecorder := recorder.New(t)

resource.Test(t, resource.TestCase{
ProviderFactories: testProviders(httpRecorder),
Steps: []resource.TestStep{
{
Config: template.ParseTestName(testAccConnectionOktaConfig, t.Name()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_connection.okta", "name", fmt.Sprintf("Acceptance-Test-Okta-%s", t.Name())),
resource.TestCheckResourceAttr("auth0_connection.okta", "strategy", "okta"),
resource.TestCheckResourceAttr("auth0_connection.okta", "show_as_button", "true"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.client_id", "123456"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.client_secret", "123456"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.domain_aliases.#", "2"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.domain_aliases.*", "example.com"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.domain_aliases.*", "api.example.com"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.issuer", "https://domain.okta.com"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.jwks_uri", "https://domain.okta.com/oauth2/v1/keys"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.token_endpoint", "https://domain.okta.com/oauth2/v1/token"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.userinfo_endpoint", "https://domain.okta.com/oauth2/v1/userinfo"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.authorization_endpoint", "https://domain.okta.com/oauth2/v1/authorize"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.scopes.#", "3"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.scopes.*", "openid"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.scopes.*", "profile"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.scopes.*", "email"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.set_user_root_attributes", "on_each_login"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.non_persistent_attrs.*", "gender"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.non_persistent_attrs.*", "hair_color"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.upstream_params", `{"screen_name":{"alias":"login_hint"}}`),
),
},
{
Config: template.ParseTestName(testAccConnectionOktaConfigUpdate, t.Name()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_connection.okta", "name", fmt.Sprintf("Acceptance-Test-Okta-%s", t.Name())),
resource.TestCheckResourceAttr("auth0_connection.okta", "strategy", "okta"),
resource.TestCheckResourceAttr("auth0_connection.okta", "show_as_button", "false"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.client_id", "123456"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.client_secret", "123456"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.domain_aliases.#", "1"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.domain_aliases.*", "example.com"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.issuer", "https://domain.okta.com"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.jwks_uri", "https://domain.okta.com/oauth2/v2/keys"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.token_endpoint", "https://domain.okta.com/oauth2/v2/token"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.userinfo_endpoint", "https://domain.okta.com/oauth2/v2/userinfo"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.authorization_endpoint", "https://domain.okta.com/oauth2/v2/authorize"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.scopes.#", "2"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.scopes.*", "openid"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.scopes.*", "profile"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.set_user_root_attributes", "on_first_login"),
resource.TestCheckTypeSetElemAttr("auth0_connection.okta", "options.0.non_persistent_attrs.*", "gender"),
resource.TestCheckResourceAttr("auth0_connection.okta", "options.0.upstream_params", ""),
),
},
},
})
}

const testAccConnectionOktaConfig = `
resource "auth0_connection" "okta" {
name = "Acceptance-Test-Okta-{{.testName}}"
display_name = "Acceptance-Test-Okta-{{.testName}}"
strategy = "okta"
show_as_button = true
options {
client_id = "123456"
client_secret = "123456"
domain = "domain.okta.com"
domain_aliases = [ "example.com", "api.example.com" ]
issuer = "https://domain.okta.com"
jwks_uri = "https://domain.okta.com/oauth2/v1/keys"
token_endpoint = "https://domain.okta.com/oauth2/v1/token"
userinfo_endpoint = "https://domain.okta.com/oauth2/v1/userinfo"
authorization_endpoint = "https://domain.okta.com/oauth2/v1/authorize"
scopes = [ "openid", "profile", "email" ]
non_persistent_attrs = [ "gender", "hair_color" ]
set_user_root_attributes = "on_each_login"
upstream_params = jsonencode({
"screen_name": {
"alias": "login_hint"
}
})
}
}
`

const testAccConnectionOktaConfigUpdate = `
resource "auth0_connection" "okta" {
name = "Acceptance-Test-Okta-{{.testName}}"
display_name = "Acceptance-Test-Okta-{{.testName}}"
strategy = "okta"
show_as_button = false
options {
client_id = "123456"
client_secret = "123456"
domain = "domain.okta.com"
domain_aliases = [ "example.com" ]
issuer = "https://domain.okta.com"
jwks_uri = "https://domain.okta.com/oauth2/v2/keys"
token_endpoint = "https://domain.okta.com/oauth2/v2/token"
userinfo_endpoint = "https://domain.okta.com/oauth2/v2/userinfo"
authorization_endpoint = "https://domain.okta.com/oauth2/v2/authorize"
scopes = [ "openid", "profile"]
non_persistent_attrs = [ "gender" ]
set_user_root_attributes = "on_first_login"
}
}
`

func TestAccConnectionOAuth2(t *testing.T) {
httpRecorder := recorder.New(t)

Expand Down
56 changes: 56 additions & 0 deletions internal/provider/structure_auth0_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ func flattenConnectionOptions(d *schema.ResourceData, options interface{}) ([]in
m, diags = flattenConnectionOptionsSMS(connectionOptions)
case *management.ConnectionOptionsOIDC:
m, diags = flattenConnectionOptionsOIDC(connectionOptions)
case *management.ConnectionOptionsOkta:
m, diags = flattenConnectionOptionsOkta(connectionOptions)
case *management.ConnectionOptionsAD:
m, diags = flattenConnectionOptionsAD(connectionOptions)
case *management.ConnectionOptionsAzureAD:
Expand Down Expand Up @@ -399,6 +401,31 @@ func flattenConnectionOptionsOIDC(options *management.ConnectionOptionsOIDC) (in
return m, nil
}

func flattenConnectionOptionsOkta(options *management.ConnectionOptionsOkta) (interface{}, diag.Diagnostics) {
m := map[string]interface{}{
"client_id": options.GetClientID(),
"client_secret": options.GetClientSecret(),
"domain": options.GetDomain(),
"domain_aliases": options.GetDomainAliases(),
"scopes": options.Scopes(),
"issuer": options.GetIssuer(),
"jwks_uri": options.GetJWKSURI(),
"token_endpoint": options.GetTokenEndpoint(),
"userinfo_endpoint": options.GetUserInfoEndpoint(),
"authorization_endpoint": options.GetAuthorizationEndpoint(),
"non_persistent_attrs": options.GetNonPersistentAttrs(),
"set_user_root_attributes": options.GetSetUserAttributes(),
}

upstreamParams, err := structure.FlattenJsonToString(options.UpstreamParams)
if err != nil {
return nil, diag.FromErr(err)
}
m["upstream_params"] = upstreamParams

return m, nil
}

func flattenConnectionOptionsEmail(options *management.ConnectionOptionsEmail) (interface{}, diag.Diagnostics) {
m := map[string]interface{}{
"name": options.GetName(),
Expand Down Expand Up @@ -647,6 +674,9 @@ func expandConnection(d *schema.ResourceData) (*management.Connection, diag.Diag
case management.ConnectionStrategyOIDC:
connection.ShowAsButton = showAsButton
connection.Options, diagnostics = expandConnectionOptionsOIDC(d, options)
case management.ConnectionStrategyOkta:
connection.ShowAsButton = showAsButton
connection.Options, diagnostics = expandConnectionOptionsOkta(d, options)
case management.ConnectionStrategyAD:
connection.ShowAsButton = showAsButton
connection.Options, diagnostics = expandConnectionOptionsAD(options)
Expand Down Expand Up @@ -1157,6 +1187,32 @@ func expandConnectionOptionsOIDC(
return options, diag.FromErr(err)
}

func expandConnectionOptionsOkta(
d *schema.ResourceData,
config cty.Value,
) (*management.ConnectionOptionsOkta, diag.Diagnostics) {
options := &management.ConnectionOptionsOkta{
ClientID: value.String(config.GetAttr("client_id")),
ClientSecret: value.String(config.GetAttr("client_secret")),
Domain: value.String(config.GetAttr("domain")),
DomainAliases: value.Strings(config.GetAttr("domain_aliases")),
AuthorizationEndpoint: value.String(config.GetAttr("authorization_endpoint")),
Issuer: value.String(config.GetAttr("issuer")),
JWKSURI: value.String(config.GetAttr("jwks_uri")),
UserInfoEndpoint: value.String(config.GetAttr("userinfo_endpoint")),
TokenEndpoint: value.String(config.GetAttr("token_endpoint")),
NonPersistentAttrs: value.Strings(config.GetAttr("non_persistent_attrs")),
SetUserAttributes: value.String(config.GetAttr("set_user_root_attributes")),
}

expandConnectionOptionsScopes(d, options)

var err error
options.UpstreamParams, err = value.MapFromJSON(config.GetAttr("upstream_params"))

return options, diag.FromErr(err)
}

func expandConnectionOptionsSAML(config cty.Value) (*management.ConnectionOptionsSAML, diag.Diagnostics) {
options := &management.ConnectionOptionsSAML{
Debug: value.Bool(config.GetAttr("debug")),
Expand Down
4 changes: 4 additions & 0 deletions templates/resources/connection.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ Also applies to following connection strategies: `dropbox`, `bitbucket`, `paypal

{{ tffile "examples/resources/auth0_connection/resource_with_oidc.tf" }}

### Okta Connection

{{ tffile "examples/resources/auth0_connection/resource_with_okta.tf" }}


{{- end }}

Expand Down
Loading

0 comments on commit 87f4fda

Please sign in to comment.