/
resource_okta_factor_totp.go
131 lines (120 loc) · 4.71 KB
/
resource_okta_factor_totp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package okta
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/okta/terraform-provider-okta/sdk"
)
func resourceFactorTOTP() *schema.Resource {
return &schema.Resource{
CreateContext: resourceFactorTOTPCreate,
ReadContext: resourceFactorTOTPRead,
UpdateContext: resourceFactorTOTPUpdate,
DeleteContext: resourceFactorTOTPDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Description: `Allows you to manage the time-based one-time password (TOTP) factors. A time-based one-time password (TOTP) is a
temporary passcode that is generated for user authentication. Examples of TOTP include hardware authenticators and
mobile app authenticators.
Once saved, the settings cannot be changed (except for the 'name' field). Any other change would force resource
recreation.`,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The TOTP name.",
},
"otp_length": {
Type: schema.TypeInt,
Default: 6,
Optional: true,
Description: "Length of the password. Default is `6`.",
ForceNew: true,
},
"hmac_algorithm": {
Type: schema.TypeString,
Default: "HMacSHA512",
Optional: true,
Description: "HMAC Algorithm. Valid values: `HMacSHA1`, `HMacSHA256`, `HMacSHA512`. Default is `HMacSHA512`.",
ForceNew: true,
},
"time_step": {
Type: schema.TypeInt,
Default: 15,
Optional: true,
Description: "Time step in seconds. Valid values: `15`, `30`, `60`. Default is `15`.",
ForceNew: true,
},
"clock_drift_interval": {
Type: schema.TypeInt,
Default: 3,
Optional: true,
Description: "Clock drift interval. This setting allows you to build in tolerance for any drift between the token's current time and the server's current time. Valid values: `3`, `5`, `10`. Default is `3`.",
ForceNew: true,
},
"shared_secret_encoding": {
Type: schema.TypeString,
Default: "base32",
Optional: true,
Description: "Shared secret encoding. Valid values: `base32`, `base64`, `hexadecimal`. Default is `base32`.",
ForceNew: true,
},
},
}
}
func resourceFactorTOTPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
profile := buildTotpFactorProfile(d)
responseProfile, _, err := getAPISupplementFromMetadata(m).CreateHotpFactorProfile(ctx, *profile)
if err != nil {
return diag.Errorf("failed to create TOTP factor: %v", err)
}
d.SetId(responseProfile.ID)
return resourceFactorTOTPRead(ctx, d, m)
}
func resourceFactorTOTPUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
profile := buildTotpFactorProfile(d)
_, _, err := getAPISupplementFromMetadata(m).UpdateHotpFactorProfile(ctx, d.Id(), *profile)
if err != nil {
return diag.Errorf("failed to update TOTP factor: %v", err)
}
return resourceFactorTOTPRead(ctx, d, m)
}
func resourceFactorTOTPRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
profile, resp, err := getAPISupplementFromMetadata(m).GetHotpFactorProfile(ctx, d.Id())
if err := suppressErrorOn404(resp, err); err != nil {
return diag.Errorf("failed to get TOTP factor: %v", err)
}
if profile == nil {
d.SetId("")
return nil
}
_ = d.Set("name", profile.Name)
_ = d.Set("otp_length", profile.Settings.OtpLength)
_ = d.Set("time_step", profile.Settings.TimeStep)
_ = d.Set("clock_drift_interval", profile.Settings.AcceptableAdjacentIntervals)
_ = d.Set("shared_secret_encoding", profile.Settings.Encoding)
_ = d.Set("hmac_algorithm", profile.Settings.HmacAlgorithm)
return nil
}
func resourceFactorTOTPDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
// NOTE: The publicly documented DELETE /api/v1/org/factors/hotp/profiles/{id} appears to only 501 at the present time.
_, err := getAPISupplementFromMetadata(m).DeleteHotpFactorProfile(ctx, d.Id())
if err != nil {
return diag.Errorf("failed to delete TOTP factor: %v", err)
}
return nil
}
func buildTotpFactorProfile(d *schema.ResourceData) *sdk.HotpFactorProfile {
return &sdk.HotpFactorProfile{
Name: d.Get("name").(string),
Settings: sdk.HotpFactorProfileSettings{
TimeBased: true,
OtpLength: d.Get("otp_length").(int),
TimeStep: d.Get("time_step").(int),
AcceptableAdjacentIntervals: d.Get("clock_drift_interval").(int),
Encoding: d.Get("shared_secret_encoding").(string),
HmacAlgorithm: d.Get("hmac_algorithm").(string),
},
}
}