Skip to content

Commit

Permalink
Add webauthn support to guardian resource
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiught committed Jul 3, 2022
1 parent d9edc3e commit 3caadaa
Show file tree
Hide file tree
Showing 7 changed files with 2,071 additions and 182 deletions.
183 changes: 173 additions & 10 deletions auth0/resource_auth0_guardian.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,61 @@ func newGuardian() *schema.Resource {
false,
),
},
"webauthn_roaming": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
MinItems: 0,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"user_verification": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice(
[]string{
"discouraged",
"preferred",
"required",
},
false,
),
},
"override_relying_party": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"relying_party_identifier": {
Type: schema.TypeString,
Optional: true,
Computed: true,
RequiredWith: []string{"webauthn_roaming.0.override_relying_party"},
},
},
},
},
"webauthn_platform": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
MinItems: 0,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"override_relying_party": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"relying_party_identifier": {
Type: schema.TypeString,
Optional: true,
Computed: true,
RequiredWith: []string{"webauthn_platform.0.override_relying_party"},
},
},
},
},
"phone": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -142,19 +197,40 @@ func readGuardian(ctx context.Context, d *schema.ResourceData, m interface{}) di
case "otp":
result = multierror.Append(result, d.Set("otp", factor.GetEnabled()))
case "sms":
if !factor.GetEnabled() {
result = multierror.Append(result, d.Set("phone", nil))
return diag.FromErr(result.ErrorOrNil())
result = multierror.Append(result, d.Set("phone", nil))

if factor.GetEnabled() {
phone, err := flattenPhone(api)
if err != nil {
return diag.FromErr(err)
}

result = multierror.Append(result, d.Set("phone", phone))
}
}
}
case "webauthn-roaming":
result = multierror.Append(result, d.Set("webauthn_roaming", nil))

phone, err := flattenPhone(api)
if err != nil {
return diag.FromErr(err)
}
if factor.GetEnabled() {
webAuthnRoaming, err := flattenWebAuthnRoaming(api)
if err != nil {
return diag.FromErr(err)
}

result = multierror.Append(result, d.Set("phone", phone))
result = multierror.Append(result, d.Set("webauthn_roaming", webAuthnRoaming))
}
case "webauthn-platform":
result = multierror.Append(result, d.Set("webauthn_platform", nil))

if factor.GetEnabled() {
webAuthnPlatform, err := flattenWebAuthnPlatform(api)
if err != nil {
return diag.FromErr(err)
}

result = multierror.Append(result, d.Set("webauthn_platform", webAuthnPlatform))
}
}
}

return diag.FromErr(result.ErrorOrNil())
}
Expand All @@ -177,6 +253,14 @@ func updateGuardian(ctx context.Context, d *schema.ResourceData, m interface{})
return diag.FromErr(err)
}

if err := updateWebAuthnRoaming(d, api); err != nil {
return diag.FromErr(err)
}

if err := updateWebAuthnPlatform(d, api); err != nil {
return diag.FromErr(err)
}

return readGuardian(ctx, d, m)
}

Expand All @@ -192,6 +276,9 @@ func deleteGuardian(ctx context.Context, d *schema.ResourceData, m interface{})
if err := api.Guardian.MultiFactor.OTP.Enable(false); err != nil {
return diag.FromErr(err)
}
if err := api.Guardian.MultiFactor.WebAuthnRoaming.Enable(false); err != nil {
return diag.FromErr(err)
}

d.SetId("")

Expand Down Expand Up @@ -272,6 +359,35 @@ func flattenTwilioOptions(api *management.Management) ([]interface{}, error) {
return []interface{}{m}, nil
}

func flattenWebAuthnRoaming(api *management.Management) ([]interface{}, error) {
webAuthnSettings, err := api.Guardian.MultiFactor.WebAuthnRoaming.Read()
if err != nil {
return nil, err
}

m := map[string]interface{}{
"user_verification": webAuthnSettings.GetUserVerification(),
"override_relying_party": webAuthnSettings.GetOverrideRelyingParty(),
"relying_party_identifier": webAuthnSettings.GetRelyingPartyIdentifier(),
}

return []interface{}{m}, nil
}

func flattenWebAuthnPlatform(api *management.Management) ([]interface{}, error) {
webAuthnSettings, err := api.Guardian.MultiFactor.WebAuthnPlatform.Read()
if err != nil {
return nil, err
}

m := map[string]interface{}{
"override_relying_party": webAuthnSettings.GetOverrideRelyingParty(),
"relying_party_identifier": webAuthnSettings.GetRelyingPartyIdentifier(),
}

return []interface{}{m}, nil
}

func updatePolicy(d *schema.ResourceData, api *management.Management) error {
if d.HasChange("policy") {
multiFactorPolicies := management.MultiFactorPolicies{}
Expand Down Expand Up @@ -431,3 +547,50 @@ func fromInterfaceSliceToStringSlice(from []interface{}) []string {

return stringArray
}

func updateWebAuthnRoaming(d *schema.ResourceData, api *management.Management) error {
if factorShouldBeUpdated(d, "webauthn_roaming") {
if err := api.Guardian.MultiFactor.WebAuthnRoaming.Enable(true); err != nil {
return err
}

var webAuthnSettings management.MultiFactorWebAuthnSettings

List(d, "webauthn_roaming").Elem(func(d ResourceData) {
webAuthnSettings.OverrideRelyingParty = Bool(d, "override_relying_party")
webAuthnSettings.RelyingPartyIdentifier = String(d, "relying_party_identifier")
webAuthnSettings.UserVerification = String(d, "user_verification")
})

if webAuthnSettings == (management.MultiFactorWebAuthnSettings{}) {
return nil
}

return api.Guardian.MultiFactor.WebAuthnRoaming.Update(&webAuthnSettings)
}

return api.Guardian.MultiFactor.WebAuthnRoaming.Enable(false)
}

func updateWebAuthnPlatform(d *schema.ResourceData, api *management.Management) error {
if factorShouldBeUpdated(d, "webauthn_platform") {
if err := api.Guardian.MultiFactor.WebAuthnPlatform.Enable(true); err != nil {
return err
}

var webAuthnSettings management.MultiFactorWebAuthnSettings

List(d, "webauthn_platform").Elem(func(d ResourceData) {
webAuthnSettings.OverrideRelyingParty = Bool(d, "override_relying_party")
webAuthnSettings.RelyingPartyIdentifier = String(d, "relying_party_identifier")
})

if webAuthnSettings == (management.MultiFactorWebAuthnSettings{}) {
return nil
}

return api.Guardian.MultiFactor.WebAuthnPlatform.Update(&webAuthnSettings)
}

return api.Guardian.MultiFactor.WebAuthnPlatform.Enable(false)
}
91 changes: 91 additions & 0 deletions auth0/resource_auth0_guardian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,94 @@ resource "auth0_guardian" "default" {
}
}
`

func TestAccGuardianWebAuthnRoaming(t *testing.T) {
httpRecorder := configureHTTPRecorder(t)

resource.Test(t, resource.TestCase{
ProviderFactories: testProviders(httpRecorder),
Steps: []resource.TestStep{
{
Config: testAccConfigureWebAuthnRoamingCreate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_guardian.foo", "policy", "all-applications"),
resource.TestCheckResourceAttr("auth0_guardian.foo", "webauthn_roaming.#", "1"),
),
},
{
Config: testAccConfigureWebAuthnRoamingUpdate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_guardian.foo", "policy", "all-applications"),
resource.TestCheckResourceAttr("auth0_guardian.foo", "webauthn_roaming.#", "1"),
resource.TestCheckResourceAttr("auth0_guardian.foo", "webauthn_roaming.0.user_verification", "required"),
),
},
{
Config: testAccConfigureWebAuthnRoamingDelete,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_guardian.foo", "policy", "all-applications"),
resource.TestCheckResourceAttr("auth0_guardian.foo", "webauthn_roaming.#", "0"),
),
},
},
})
}

const testAccConfigureWebAuthnRoamingCreate = `
resource "auth0_guardian" "foo" {
policy = "all-applications"
webauthn_roaming {}
}
`

const testAccConfigureWebAuthnRoamingUpdate = `
resource "auth0_guardian" "foo" {
policy = "all-applications"
webauthn_roaming {
user_verification = "required"
}
}
`

const testAccConfigureWebAuthnRoamingDelete = `
resource "auth0_guardian" "foo" {
policy = "all-applications"
}
`

func TestAccGuardianWebAuthnPlatform(t *testing.T) {
httpRecorder := configureHTTPRecorder(t)

resource.Test(t, resource.TestCase{
ProviderFactories: testProviders(httpRecorder),
Steps: []resource.TestStep{
{
Config: testAccConfigureWebAuthnPlatformCreate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_guardian.foo", "policy", "all-applications"),
resource.TestCheckResourceAttr("auth0_guardian.foo", "webauthn_platform.#", "1"),
),
},
{
Config: testAccConfigureWebAuthnPlatformDelete,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_guardian.foo", "policy", "all-applications"),
resource.TestCheckResourceAttr("auth0_guardian.foo", "webauthn_platform.#", "0"),
),
},
},
})
}

const testAccConfigureWebAuthnPlatformCreate = `
resource "auth0_guardian" "foo" {
policy = "all-applications"
webauthn_platform {}
}
`

const testAccConfigureWebAuthnPlatformDelete = `
resource "auth0_guardian" "foo" {
policy = "all-applications"
}
`
Loading

0 comments on commit 3caadaa

Please sign in to comment.