Skip to content

Commit

Permalink
pingone_mfa_device_policy: Add the totp.uri_parameters field to a…
Browse files Browse the repository at this point in the history
…llow custom key:value pairs for authenticators that support `otpauth` URI parameters
  • Loading branch information
patrickcping committed Nov 15, 2024
1 parent a0256f1 commit c7eaf41
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/resources/mfa_device_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ Optional:
- `otp` (Attributes) A single object that allows configuration of TOTP OTP settings. (see [below for nested schema](#nestedatt--totp--otp))
- `pairing_disabled` (Boolean) A boolean that, when set to `true`, prevents users from pairing new devices with the TOTP method, though keeping it active in the policy for existing users. You can use this option if you want to phase out an existing authentication method but want to allow users to continue using the method for authentication for existing devices. Defaults to `false`.
- `prompt_for_nickname_on_pairing` (Boolean) A boolean that, when set to `true`, prompts users to provide nicknames for devices during pairing.
- `uri_parameters` (Map of String) A map of string key:value pairs that specifies `otpauth` URI parameters. For example, if you provide a value for the `issuer` parameter, then authenticators that support that parameter will display the text you specify together with the OTP (in addition to the username). This can help users recognize which application the OTP is for. If you intend on using the same MFA policy for multiple applications, choose a name that reflects the group of applications.

<a id="nestedatt--totp--otp"></a>
### Nested Schema for `totp.otp`
Expand Down
35 changes: 34 additions & 1 deletion internal/service/mfa/resource_mfa_device_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ type MFADevicePolicyAuthenticationResourceModel struct {
type MFADevicePolicySmsResourceModel MFADevicePolicyOfflineDeviceResourceModel
type MFADevicePolicyVoiceResourceModel MFADevicePolicyOfflineDeviceResourceModel
type MFADevicePolicyEmailResourceModel MFADevicePolicyOfflineDeviceResourceModel
type MFADevicePolicyTotpResourceModel MFADevicePolicyOfflineDeviceResourceModel

type MFADevicePolicyTotpResourceModel struct {
Enabled types.Bool `tfsdk:"enabled"`
Otp types.Object `tfsdk:"otp"`
PairingDisabled types.Bool `tfsdk:"pairing_disabled"`
PromptForNicknameOnPairing types.Bool `tfsdk:"prompt_for_nickname_on_pairing"`
UriParameters types.Map `tfsdk:"uri_parameters"`
}

type MFADevicePolicyOfflineDeviceResourceModel struct {
Enabled types.Bool `tfsdk:"enabled"`
Expand Down Expand Up @@ -221,6 +228,7 @@ var (
"otp": types.ObjectType{AttrTypes: MFADevicePolicyTotpOtpTFObjectTypes},
"pairing_disabled": types.BoolType,
"prompt_for_nickname_on_pairing": types.BoolType,
"uri_parameters": types.MapType{ElemType: types.StringType},
}

MFADevicePolicyTotpOtpTFObjectTypes = map[string]attr.Type{
Expand Down Expand Up @@ -349,6 +357,10 @@ func (r *MFADevicePolicyResource) Schema(ctx context.Context, req resource.Schem
"A boolean that, when set to `true`, prevents users from pairing new devices with the TOTP method, though keeping it active in the policy for existing users. You can use this option if you want to phase out an existing authentication method but want to allow users to continue using the method for authentication for existing devices.",
).DefaultValue(false)

totpUriParametersDescription := framework.SchemaAttributeDescriptionFromMarkdown(
"A map of string key:value pairs that specifies `otpauth` URI parameters. For example, if you provide a value for the `issuer` parameter, then authenticators that support that parameter will display the text you specify together with the OTP (in addition to the username). This can help users recognize which application the OTP is for. If you intend on using the same MFA policy for multiple applications, choose a name that reflects the group of applications.",
)

fido2PairingDisabledDescription := framework.SchemaAttributeDescriptionFromMarkdown(
"A boolean that, when set to `true`, prevents users from pairing new devices with the FIDO2 method, though keeping it active in the policy for existing users. You can use this option if you want to phase out an existing authentication method but want to allow users to continue using the method for authentication for existing devices.",
).DefaultValue(false)
Expand Down Expand Up @@ -826,6 +838,14 @@ func (r *MFADevicePolicyResource) Schema(ctx context.Context, req resource.Schem
MarkdownDescription: promptForNicknameOnPairingDescription.MarkdownDescription,
Optional: true,
},

"uri_parameters": schema.MapAttribute{
Description: totpUriParametersDescription.Description,
MarkdownDescription: totpUriParametersDescription.MarkdownDescription,
Optional: true,

ElementType: types.StringType,
},
},
},

Expand Down Expand Up @@ -1904,10 +1924,22 @@ func (p *MFADevicePolicyTotpResourceModel) expand(ctx context.Context) (*mfa.Dev
data.SetPairingDisabled(p.PairingDisabled.ValueBool())
}

// Prompt for Nickname on Pairing
if !p.PromptForNicknameOnPairing.IsNull() && !p.PromptForNicknameOnPairing.IsUnknown() {
data.SetPromptForNicknameOnPairing(p.PromptForNicknameOnPairing.ValueBool())
}

// Uri Parameters
if !p.UriParameters.IsNull() && !p.UriParameters.IsUnknown() {
var uriParametersPlan map[string]string
diags.Append(p.UriParameters.ElementsAs(ctx, &uriParametersPlan, false)...)
if diags.HasError() {
return nil, diags
}

data.SetUriParameters(uriParametersPlan)
}

return data, diags
}

Expand Down Expand Up @@ -2502,6 +2534,7 @@ func toStateMfaDevicePolicyTotp(apiObject *mfa.DeviceAuthenticationPolicyTotp, o
"otp": otp,
"pairing_disabled": framework.BoolOkToTF(apiObject.GetPairingDisabledOk()),
"prompt_for_nickname_on_pairing": framework.BoolOkToTF(apiObject.GetPromptForNicknameOnPairingOk()),
"uri_parameters": framework.StringMapOkToTF(apiObject.GetUriParametersOk()),
}

objValue, d := types.ObjectValue(MFADevicePolicyTotpTFObjectTypes, o)
Expand Down
20 changes: 20 additions & 0 deletions internal/service/mfa/resource_mfa_device_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,10 @@ func TestAccMFADevicePolicy_Totp_Full(t *testing.T) {
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.duration", "125"),
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.time_unit", "SECONDS"),
resource.TestCheckResourceAttr(resourceFullName, "totp.prompt_for_nickname_on_pairing", "true"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.%", "3"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param1", "value 1"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param2", "value 2"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param3", "value 3"),
resource.TestCheckResourceAttr(resourceFullName, "fido2.enabled", "false"),
resource.TestCheckResourceAttr(resourceFullName, "new_device_notification", "SMS_THEN_EMAIL"),
),
Expand Down Expand Up @@ -1136,6 +1140,7 @@ func TestAccMFADevicePolicy_Totp_Minimal(t *testing.T) {
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.duration", "2"),
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.time_unit", "MINUTES"),
resource.TestCheckNoResourceAttr(resourceFullName, "totp.prompt_for_nickname_on_pairing"),
resource.TestCheckNoResourceAttr(resourceFullName, "totp.uri_parameters"),
resource.TestCheckResourceAttr(resourceFullName, "fido2.enabled", "false"),
resource.TestCheckResourceAttr(resourceFullName, "new_device_notification", "NONE"),
),
Expand Down Expand Up @@ -1174,6 +1179,10 @@ func TestAccMFADevicePolicy_Totp_Change(t *testing.T) {
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.duration", "125"),
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.time_unit", "SECONDS"),
resource.TestCheckResourceAttr(resourceFullName, "totp.prompt_for_nickname_on_pairing", "true"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.%", "3"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param1", "value 1"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param2", "value 2"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param3", "value 3"),
resource.TestCheckResourceAttr(resourceFullName, "fido2.enabled", "false"),
resource.TestCheckResourceAttr(resourceFullName, "new_device_notification", "SMS_THEN_EMAIL"),
),
Expand All @@ -1191,6 +1200,7 @@ func TestAccMFADevicePolicy_Totp_Change(t *testing.T) {
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.duration", "2"),
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.time_unit", "MINUTES"),
resource.TestCheckNoResourceAttr(resourceFullName, "totp.prompt_for_nickname_on_pairing"),
resource.TestCheckNoResourceAttr(resourceFullName, "totp.uri_parameters"),
resource.TestCheckResourceAttr(resourceFullName, "fido2.enabled", "false"),
resource.TestCheckResourceAttr(resourceFullName, "new_device_notification", "NONE"),
),
Expand All @@ -1208,6 +1218,10 @@ func TestAccMFADevicePolicy_Totp_Change(t *testing.T) {
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.duration", "125"),
resource.TestCheckResourceAttr(resourceFullName, "totp.otp.failure.cool_down.time_unit", "SECONDS"),
resource.TestCheckResourceAttr(resourceFullName, "totp.prompt_for_nickname_on_pairing", "true"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.%", "3"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param1", "value 1"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param2", "value 2"),
resource.TestCheckResourceAttr(resourceFullName, "totp.uri_parameters.param3", "value 3"),
resource.TestCheckResourceAttr(resourceFullName, "fido2.enabled", "false"),
resource.TestCheckResourceAttr(resourceFullName, "new_device_notification", "SMS_THEN_EMAIL"),
),
Expand Down Expand Up @@ -2774,6 +2788,12 @@ resource "pingone_mfa_device_policy" "%[2]s" {
prompt_for_nickname_on_pairing = true
uri_parameters = {
"param1" = "value 1"
"param3" = "value 3"
"param2" = "value 2"
}
otp = {
failure = {
count = 5
Expand Down

0 comments on commit c7eaf41

Please sign in to comment.