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

issue#428: Add support for ping federate connections #527

Merged
merged 6 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions docs/data-sources/connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Read-Only:
- `password_history` (List of Object) (see [below for nested schema](#nestedobjatt--options--password_history))
- `password_no_personal_info` (List of Object) (see [below for nested schema](#nestedobjatt--options--password_no_personal_info))
- `password_policy` (String)
- `ping_federate_base_url` (String)
- `pkce_enabled` (Boolean)
- `protocol_binding` (String)
- `provider` (String)
Expand Down
1 change: 1 addition & 0 deletions docs/resources/connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ Optional:
- `password_history` (Block List) Configuration settings for the password history that is maintained for each user to prevent the reuse of passwords. (see [below for nested schema](#nestedblock--options--password_history))
- `password_no_personal_info` (Block List, Max: 1) Configuration settings for the password personal info check, which does not allow passwords that contain any part of the user's personal data, including user's `name`, `username`, `nickname`, `user_metadata.name`, `user_metadata.first`, `user_metadata.last`, user's `email`, or first part of the user's `email`. (see [below for nested schema](#nestedblock--options--password_no_personal_info))
- `password_policy` (String) Indicates level of password strength to enforce during authentication. A strong password policy will make it difficult, if not improbable, for someone to guess a password through either manual or automated means. Options include `none`, `low`, `fair`, `good`, `excellent`.
- `ping_federate_base_url` (String) Ping Federate Server URL.
- `pkce_enabled` (Boolean) Enables Proof Key for Code Exchange (PKCE) functionality for OAuth2 connections.
- `protocol_binding` (String) The SAML Response Binding: how the SAML token is received by Auth0 from the IdP.
- `provider` (String) Defines the custom `sms_gateway` provider.
Expand Down
36 changes: 36 additions & 0 deletions internal/auth0/connection/expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ func expandConnection(d *schema.ResourceData, api *management.Management) (*mana
case management.ConnectionStrategyADFS:
connection.ShowAsButton = showAsButton
connection.Options, diagnostics = expandConnectionOptionsADFS(options)
case management.ConnectionStrategyPingFederate:
connection.ShowAsButton = showAsButton
connection.Options, diagnostics = expandConnectionOptionsPingFederate(options)
default:
diagnostics = append(diagnostics, diag.Diagnostic{
Severity: diag.Error,
Expand Down Expand Up @@ -723,6 +726,39 @@ func expandConnectionOptionsADFS(config cty.Value) (*management.ConnectionOption
return options, diag.FromErr(err)
}

func expandConnectionOptionsPingFederate(
config cty.Value,
) (*management.ConnectionOptionsPingFederate, diag.Diagnostics) {
options := &management.ConnectionOptionsPingFederate{
SigningCert: value.String(config.GetAttr("signing_cert")),
LogoURL: value.String(config.GetAttr("icon_url")),
TenantDomain: value.String(config.GetAttr("tenant_domain")),
DomainAliases: value.Strings(config.GetAttr("domain_aliases")),
SignInEndpoint: value.String(config.GetAttr("sign_in_endpoint")),
DigestAlgorithm: value.String(config.GetAttr("digest_algorithm")),
SignSAMLRequest: value.Bool(config.GetAttr("sign_saml_request")),
SignatureAlgorithm: value.String(config.GetAttr("signature_algorithm")),
PingFederateBaseURL: value.String(config.GetAttr("ping_federate_base_url")),
NonPersistentAttrs: value.Strings(config.GetAttr("non_persistent_attrs")),
SetUserAttributes: value.String(config.GetAttr("set_user_root_attributes")),
}

config.GetAttr("idp_initiated").ForEachElement(func(_ cty.Value, idp cty.Value) (stop bool) {
options.IdpInitiated = &management.ConnectionOptionsSAMLIdpInitiated{
ClientID: value.String(idp.GetAttr("client_id")),
ClientProtocol: value.String(idp.GetAttr("client_protocol")),
ClientAuthorizeQuery: value.String(idp.GetAttr("client_authorize_query")),
}

return stop
})

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

return options, diag.FromErr(err)
}

type scoper interface {
Scopes() []string
SetScopes(enable bool, scopes ...string)
Expand Down
41 changes: 41 additions & 0 deletions internal/auth0/connection/flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func flattenConnectionOptions(d *schema.ResourceData, options interface{}) ([]in
m, diags = flattenConnectionOptionsAzureAD(connectionOptions)
case *management.ConnectionOptionsADFS:
m, diags = flattenConnectionOptionsADFS(connectionOptions)
case *management.ConnectionOptionsPingFederate:
m, diags = flattenConnectionOptionsPingFederate(connectionOptions)
case *management.ConnectionOptionsSAML:
m, diags = flattenConnectionOptionsSAML(d, connectionOptions)
}
Expand Down Expand Up @@ -601,3 +603,42 @@ func flattenConnectionOptionsSAML(

return m, nil
}

func flattenConnectionOptionsPingFederate(
options *management.ConnectionOptionsPingFederate,
) (interface{}, diag.Diagnostics) {
signingCert := options.GetSigningCert()
if signingCert == "" {
signingCert = options.GetCert()
}

m := map[string]interface{}{
"signing_cert": signingCert,
"tenant_domain": options.GetTenantDomain(),
"domain_aliases": options.GetDomainAliases(),
"sign_in_endpoint": options.GetSignInEndpoint(),
"signature_algorithm": options.GetSignatureAlgorithm(),
"digest_algorithm": options.GetDigestAlgorithm(),
"sign_saml_request": options.GetSignSAMLRequest(),
"ping_federate_base_url": options.GetPingFederateBaseURL(),
"icon_url": options.GetLogoURL(),
"set_user_root_attributes": options.GetSetUserAttributes(),
"non_persistent_attrs": options.GetNonPersistentAttrs(),
}

m["idp_initiated"] = []interface{}{
map[string]interface{}{
"client_id": options.GetIdpInitiated().GetClientID(),
"client_protocol": options.GetIdpInitiated().GetClientProtocol(),
"client_authorize_query": options.GetIdpInitiated().GetClientAuthorizeQuery(),
},
}

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

return m, nil
}
173 changes: 173 additions & 0 deletions internal/auth0/connection/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1719,3 +1719,176 @@ resource "auth0_connection" "twitter" {
}
}
`

func TestAccConnectionPingFederate(t *testing.T) {
acctest.Test(t, resource.TestCase{
Steps: []resource.TestStep{
{
Config: acctest.ParseTestName(testConnectionPingFederateConfigCreate, t.Name()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_connection.my_connection", "name", fmt.Sprintf("Acceptance-Test-PingFederate-%s", t.Name())),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "display_name", fmt.Sprintf("Acceptance-Test-PingFederate-%s", t.Name())),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "strategy", "pingfederate"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "show_as_button", "false"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.#", "1"),
resource.TestCheckResourceAttrSet("auth0_connection.my_connection", "options.0.signing_cert"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.tenant_domain", "example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.ping_federate_base_url", "https://pingfederate.example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.sign_in_endpoint", "https://pingfederate.example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.domain_aliases.#", "2"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.domain_aliases.0", "example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.domain_aliases.1", "example.coz"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.signature_algorithm", "rsa-sha256"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.sign_saml_request", "false"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.digest_algorithm", "sha256"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.icon_url", "https://example.com/logo.svg"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.set_user_root_attributes", "on_first_login"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.non_persistent_attrs.#", "2"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.non_persistent_attrs.0", "gender"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.non_persistent_attrs.1", "hair_color"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.#", "1"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.0.client_id", "client_id"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.0.client_protocol", "samlp"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.0.client_authorize_query", "type=code&timeout=30"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.upstream_params", "{\"screen_name\":{\"alias\":\"login_hint\"}}"),
),
},
{
Config: template.ParseTestName(testConnectionPingFederateConfigUpdate, t.Name()),
sergiught marked this conversation as resolved.
Show resolved Hide resolved
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_connection.my_connection", "name", fmt.Sprintf("Acceptance-Test-PingFederate-%s", t.Name())),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "display_name", fmt.Sprintf("Acceptance-Test-PingFederate-%s", t.Name())),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "strategy", "pingfederate"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "show_as_button", "true"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.#", "1"),
resource.TestCheckResourceAttrSet("auth0_connection.my_connection", "options.0.signing_cert"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.tenant_domain", "example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.ping_federate_base_url", "https://pingfederate.example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.sign_in_endpoint", "https://pingfederate.example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.domain_aliases.#", "2"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.domain_aliases.0", "example.com"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.domain_aliases.1", "example.coz"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.signature_algorithm", "rsa-sha256"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.sign_saml_request", "true"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.digest_algorithm", "sha256"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.icon_url", ""),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.set_user_root_attributes", "on_first_login"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.non_persistent_attrs.#", "2"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.non_persistent_attrs.0", "gender"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.non_persistent_attrs.1", "hair_color"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.#", "1"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.0.client_id", "client_id"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.0.client_protocol", "samlp"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.idp_initiated.0.client_authorize_query", "type=code&timeout=60"),
resource.TestCheckResourceAttr("auth0_connection.my_connection", "options.0.upstream_params", ""),
),
},
},
})
}

const testConnectionPingFederateConfigCreate = `
resource "auth0_connection" "my_connection" {
name = "Acceptance-Test-PingFederate-{{.testName}}"
display_name = "Acceptance-Test-PingFederate-{{.testName}}"
strategy = "pingfederate"
show_as_button = false
options {
signing_cert = <<EOF
-----BEGIN CERTIFICATE-----
MIID6TCCA1ICAQEwDQYJKoZIhvcNAQEFBQAwgYsxCzAJBgNVBAYTAlVTMRMwEQYD
VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQK
EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq
hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw
OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf
BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh
LnNmby5jb3JwLmdvb2dsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQC6pgYt7/EibBDumASF+S0qvqdL/f+nouJw2T1Qc8GmXF/iiUcrsgzh/Fd8
pDhz/T96Qg9IyR4ztuc2MXrmPra+zAuSf5bevFReSqvpIt8Duv0HbDbcqs/XKPfB
uMDe+of7a9GCywvAZ4ZUJcp0thqD9fKTTjUWOBzHY1uNE4RitrhmJCrbBGXbJ249
bvgmb7jgdInH2PU7PT55hujvOoIsQW2osXBFRur4pF1wmVh4W4lTLD6pjfIMUcML
ICHEXEN73PDic8KS3EtNYCwoIld+tpIBjE1QOb1KOyuJBNW6Esw9ALZn7stWdYcE
qAwvv20egN2tEXqj7Q4/1ccyPZc3PQgC3FJ8Be2mtllM+80qf4dAaQ/fWvCtOrQ5
pnfe9juQvCo8Y0VGlFcrSys/MzSg9LJ/24jZVgzQved/Qupsp89wVidwIzjt+WdS
fyWfH0/v1aQLvu5cMYuW//C0W2nlYziL5blETntM8My2ybNARy3ICHxCBv2RNtPI
WQVm+E9/W5rwh2IJR4DHn2LHwUVmT/hHNTdBLl5Uhwr4Wc7JhE7AVqb14pVNz1lr
5jxsp//ncIwftb7mZQ3DF03Yna+jJhpzx8CQoeLT6aQCHyzmH68MrHHT4MALPyUs
Pomjn71GNTtDeWAXibjCgdL6iHACCF6Htbl0zGlG0OAK+bdn0QIDAQABMA0GCSqG
SIb3DQEBBQUAA4GBAOKnQDtqBV24vVqvesL5dnmyFpFPXBn3WdFfwD6DzEb21UVG
5krmJiu+ViipORJPGMkgoL6BjU21XI95VQbun5P8vvg8Z+FnFsvRFY3e1CCzAVQY
ZsUkLw2I7zI/dNlWdB8Xp7v+3w9sX5N3J/WuJ1KOO5m26kRlHQo7EzT3974g
-----END CERTIFICATE-----
EOF
tenant_domain = "example.com"
ping_federate_base_url = "https://pingfederate.example.com"
sign_in_endpoint = "https://pingfederate.example.com"
domain_aliases = ["example.com", "example.coz"]
signature_algorithm = "rsa-sha256"
sign_saml_request = false
digest_algorithm = "sha256"
icon_url = "https://example.com/logo.svg"
set_user_root_attributes = "on_first_login"
non_persistent_attrs = ["gender","hair_color"]
upstream_params = jsonencode({
"screen_name": {
"alias": "login_hint"
}
})
idp_initiated {
client_id = "client_id"
client_protocol = "samlp"
client_authorize_query = "type=code&timeout=30"
}
}
}
`

const testConnectionPingFederateConfigUpdate = `
resource "auth0_connection" "my_connection" {
name = "Acceptance-Test-PingFederate-{{.testName}}"
display_name = "Acceptance-Test-PingFederate-{{.testName}}"
strategy = "pingfederate"
show_as_button = true
options {
signing_cert = <<EOF
-----BEGIN CERTIFICATE-----
MIID6TCCA1ICAQEwDQYJKoZIhvcNAQEFBQAwgYsxCzAJBgNVBAYTAlVTMRMwEQYD
VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQK
EwtHb29nbGUgSW5jLjEMMAoGA1UECxMDRW5nMQwwCgYDVQQDEwNhZ2wxHTAbBgkq
hkiG9w0BCQEWDmFnbEBnb29nbGUuY29tMB4XDTA5MDkwOTIyMDU0M1oXDTEwMDkw
OTIyMDU0M1owajELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAf
BgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGA1UEAxMaZXVyb3Bh
LnNmby5jb3JwLmdvb2dsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQC6pgYt7/EibBDumASF+S0qvqdL/f+nouJw2T1Qc8GmXF/iiUcrsgzh/Fd8
pDhz/T96Qg9IyR4ztuc2MXrmPra+zAuSf5bevFReSqvpIt8Duv0HbDbcqs/XKPfB
uMDe+of7a9GCywvAZ4ZUJcp0thqD9fKTTjUWOBzHY1uNE4RitrhmJCrbBGXbJ249
bvgmb7jgdInH2PU7PT55hujvOoIsQW2osXBFRur4pF1wmVh4W4lTLD6pjfIMUcML
ICHEXEN73PDic8KS3EtNYCwoIld+tpIBjE1QOb1KOyuJBNW6Esw9ALZn7stWdYcE
qAwvv20egN2tEXqj7Q4/1ccyPZc3PQgC3FJ8Be2mtllM+80qf4dAaQ/fWvCtOrQ5
pnfe9juQvCo8Y0VGlFcrSys/MzSg9LJ/24jZVgzQved/Qupsp89wVidwIzjt+WdS
fyWfH0/v1aQLvu5cMYuW//C0W2nlYziL5blETntM8My2ybNARy3ICHxCBv2RNtPI
WQVm+E9/W5rwh2IJR4DHn2LHwUVmT/hHNTdBLl5Uhwr4Wc7JhE7AVqb14pVNz1lr
5jxsp//ncIwftb7mZQ3DF03Yna+jJhpzx8CQoeLT6aQCHyzmH68MrHHT4MALPyUs
Pomjn71GNTtDeWAXibjCgdL6iHACCF6Htbl0zGlG0OAK+bdn0QIDAQABMA0GCSqG
SIb3DQEBBQUAA4GBAOKnQDtqBV24vVqvesL5dnmyFpFPXBn3WdFfwD6DzEb21UVG
5krmJiu+ViipORJPGMkgoL6BjU21XI95VQbun5P8vvg8Z+FnFsvRFY3e1CCzAVQY
ZsUkLw2I7zI/dNlWdB8Xp7v+3w9sX5N3J/WuJ1KOO5m26kRlHQo7EzT3974g
-----END CERTIFICATE-----
EOF
tenant_domain = "example.com"
ping_federate_base_url = "https://pingfederate.example.com"
sign_in_endpoint = "https://pingfederate.example.com"
domain_aliases = ["example.com", "example.coz"]
signature_algorithm = "rsa-sha256"
sign_saml_request = true
digest_algorithm = "sha256"
set_user_root_attributes = "on_first_login"
non_persistent_attrs = ["gender","hair_color"]
idp_initiated {
client_id = "client_id"
client_protocol = "samlp"
client_authorize_query = "type=code&timeout=60"
}
}
}
`
7 changes: 7 additions & 0 deletions internal/auth0/connection/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

internalSchema "github.com/auth0/terraform-provider-auth0/internal/schema"
internalValidation "github.com/auth0/terraform-provider-auth0/internal/validation"
)

var resourceSchema = map[string]*schema.Schema{
Expand Down Expand Up @@ -323,6 +324,12 @@ var resourceSchema = map[string]*schema.Schema{
Optional: true,
Description: "Icon URL.",
},
"ping_federate_base_url": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: internalValidation.IsURLWithHTTPSorEmptyString,
sergiught marked this conversation as resolved.
Show resolved Hide resolved
Description: "Ping Federate Server URL.",
},
"identity_api": {
Type: schema.TypeString,
Optional: true,
Expand Down
Loading