From 8b11307ae704ef1ae2a6b23657ac1c0d5d8541a9 Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea Date: Sun, 3 Jul 2022 13:45:12 +0200 Subject: [PATCH] Add read and update to Duo Settings --- management/guardian.go | 22 ++++++ management/guardian_test.go | 46 ++++++++--- management/management.gen.go | 29 +++++++ management/management.gen_test.go | 38 +++++++++ .../{DUO_Enable.yaml => DUO/Enable.yaml} | 4 +- .../MultiFactor/DUO/Settings.yaml | 79 +++++++++++++++++++ 6 files changed, 206 insertions(+), 12 deletions(-) rename management/testdata/recordings/TestGuardian/MultiFactor/{DUO_Enable.yaml => DUO/Enable.yaml} (68%) create mode 100644 management/testdata/recordings/TestGuardian/MultiFactor/DUO/Settings.yaml diff --git a/management/guardian.go b/management/guardian.go index 83ae54fb..b0da5ce4 100644 --- a/management/guardian.go +++ b/management/guardian.go @@ -342,6 +342,13 @@ func (m *MultiFactorEmail) Enable(enabled bool, opts ...RequestOption) error { }, opts...) } +// MultiFactorDUOSettings holds settings for configuring DUO. +type MultiFactorDUOSettings struct { + Hostname *string `json:"host,omitempty"` + IntegrationKey *string `json:"ikey,omitempty"` + SecretKey *string `json:"skey,omitempty"` +} + // MultiFactorDUO is used for Duo MFA. type MultiFactorDUO struct{ *Management } @@ -354,6 +361,21 @@ func (m *MultiFactorDUO) Enable(enabled bool, opts ...RequestOption) error { }, opts...) } +// Read WebAuthn Roaming Multi-factor Authentication Settings. +// +// See: https://auth0.com/docs/secure/multi-factor-authentication/configure-cisco-duo-for-mfa +func (m *MultiFactorDUO) Read(opts ...RequestOption) (s *MultiFactorDUOSettings, err error) { + err = m.Request("GET", m.URI("guardian", "factors", "duo", "settings"), &s, opts...) + return +} + +// Update WebAuthn Roaming Multi-factor Authentication Settings. +// +// See: https://auth0.com/docs/secure/multi-factor-authentication/configure-cisco-duo-for-mfa +func (m *MultiFactorDUO) Update(s *MultiFactorDUOSettings, opts ...RequestOption) error { + return m.Request("PUT", m.URI("guardian", "factors", "duo", "settings"), &s, opts...) +} + // MultiFactorWebAuthnSettings holds settings for // configuring WebAuthn Roaming or Platform. type MultiFactorWebAuthnSettings struct { diff --git a/management/guardian_test.go b/management/guardian_test.go index 680de639..dbe7e900 100644 --- a/management/guardian_test.go +++ b/management/guardian_test.go @@ -233,20 +233,46 @@ func TestGuardian(t *testing.T) { assertMFAIsEnabled(t, "email") }) - t.Run("DUO Enable", func(t *testing.T) { - setupHTTPRecordings(t) + t.Run("DUO", func(t *testing.T) { + t.Run("Enable", func(t *testing.T) { + setupHTTPRecordings(t) - initialStatus, err := getInitialMFAStatus("duo") - assert.NoError(t, err) + initialStatus, err := getInitialMFAStatus("duo") + assert.NoError(t, err) - t.Cleanup(func() { - err := m.Guardian.MultiFactor.DUO.Enable(initialStatus) - require.NoError(t, err) + t.Cleanup(func() { + err := m.Guardian.MultiFactor.DUO.Enable(initialStatus) + require.NoError(t, err) + }) + + err = m.Guardian.MultiFactor.DUO.Enable(true) + assert.NoError(t, err) + assertMFAIsEnabled(t, "duo") }) + t.Run("Settings", func(t *testing.T) { + setupHTTPRecordings(t) - err = m.Guardian.MultiFactor.DUO.Enable(true) - assert.NoError(t, err) - assertMFAIsEnabled(t, "duo") + initialSettings, err := m.Guardian.MultiFactor.DUO.Read() + assert.NoError(t, err) + t.Cleanup(func() { + err := m.Guardian.MultiFactor.DUO.Update(initialSettings) + require.NoError(t, err) + }) + + updatedSettings := &MultiFactorDUOSettings{ + Hostname: auth0.String("api-hostname"), + IntegrationKey: auth0.String("someKey"), + SecretKey: auth0.String("someSecret"), + } + err = m.Guardian.MultiFactor.DUO.Update(updatedSettings) + assert.NoError(t, err) + + actualSettings, err := m.Guardian.MultiFactor.DUO.Read() + assert.NoError(t, err) + assert.Equal(t, "api-hostname", actualSettings.GetHostname()) + assert.Equal(t, "someKey", actualSettings.GetIntegrationKey()) + assert.Equal(t, "someSecret", actualSettings.GetSecretKey()) + }) }) t.Run("OTP Enable", func(t *testing.T) { diff --git a/management/management.gen.go b/management/management.gen.go index 23c4fc5f..f0dde869 100644 --- a/management/management.gen.go +++ b/management/management.gen.go @@ -4533,6 +4533,35 @@ func (m *MultiFactorDUO) String() string { return Stringify(m) } +// GetHostname returns the Hostname field if it's non-nil, zero value otherwise. +func (m *MultiFactorDUOSettings) GetHostname() string { + if m == nil || m.Hostname == nil { + return "" + } + return *m.Hostname +} + +// GetIntegrationKey returns the IntegrationKey field if it's non-nil, zero value otherwise. +func (m *MultiFactorDUOSettings) GetIntegrationKey() string { + if m == nil || m.IntegrationKey == nil { + return "" + } + return *m.IntegrationKey +} + +// GetSecretKey returns the SecretKey field if it's non-nil, zero value otherwise. +func (m *MultiFactorDUOSettings) GetSecretKey() string { + if m == nil || m.SecretKey == nil { + return "" + } + return *m.SecretKey +} + +// String returns a string representation of MultiFactorDUOSettings. +func (m *MultiFactorDUOSettings) String() string { + return Stringify(m) +} + // String returns a string representation of MultiFactorEmail. func (m *MultiFactorEmail) String() string { return Stringify(m) diff --git a/management/management.gen_test.go b/management/management.gen_test.go index b7f9bce4..88b1b5dd 100644 --- a/management/management.gen_test.go +++ b/management/management.gen_test.go @@ -5749,6 +5749,44 @@ func TestMultiFactorDUO_String(t *testing.T) { } } +func TestMultiFactorDUOSettings_GetHostname(tt *testing.T) { + var zeroValue string + m := &MultiFactorDUOSettings{Hostname: &zeroValue} + m.GetHostname() + m = &MultiFactorDUOSettings{} + m.GetHostname() + m = nil + m.GetHostname() +} + +func TestMultiFactorDUOSettings_GetIntegrationKey(tt *testing.T) { + var zeroValue string + m := &MultiFactorDUOSettings{IntegrationKey: &zeroValue} + m.GetIntegrationKey() + m = &MultiFactorDUOSettings{} + m.GetIntegrationKey() + m = nil + m.GetIntegrationKey() +} + +func TestMultiFactorDUOSettings_GetSecretKey(tt *testing.T) { + var zeroValue string + m := &MultiFactorDUOSettings{SecretKey: &zeroValue} + m.GetSecretKey() + m = &MultiFactorDUOSettings{} + m.GetSecretKey() + m = nil + m.GetSecretKey() +} + +func TestMultiFactorDUOSettings_String(t *testing.T) { + var rawJSON json.RawMessage + v := &MultiFactorDUOSettings{} + if err := json.Unmarshal([]byte(v.String()), &rawJSON); err != nil { + t.Errorf("failed to produce a valid json") + } +} + func TestMultiFactorEmail_String(t *testing.T) { var rawJSON json.RawMessage v := &MultiFactorEmail{} diff --git a/management/testdata/recordings/TestGuardian/MultiFactor/DUO_Enable.yaml b/management/testdata/recordings/TestGuardian/MultiFactor/DUO/Enable.yaml similarity index 68% rename from management/testdata/recordings/TestGuardian/MultiFactor/DUO_Enable.yaml rename to management/testdata/recordings/TestGuardian/MultiFactor/DUO/Enable.yaml index b544fb0b..6cc79095 100644 --- a/management/testdata/recordings/TestGuardian/MultiFactor/DUO_Enable.yaml +++ b/management/testdata/recordings/TestGuardian/MultiFactor/DUO/Enable.yaml @@ -13,7 +13,7 @@ interactions: url: https://go-auth0-dev.eu.auth0.com/api/v2/guardian/factors method: GET response: - body: '[{"name":"sms","enabled":true,"trial_expired":false},{"name":"push-notification","enabled":false,"trial_expired":false},{"name":"otp","enabled":false,"trial_expired":false},{"name":"email","enabled":false,"trial_expired":false},{"name":"duo","enabled":false,"trial_expired":false},{"name":"webauthn-roaming","enabled":false,"trial_expired":false},{"name":"webauthn-platform","enabled":false,"trial_expired":false},{"name":"recovery-code","enabled":false,"trial_expired":false}]' + body: '[{"name":"sms","enabled":false,"trial_expired":false},{"name":"push-notification","enabled":false,"trial_expired":false},{"name":"otp","enabled":false,"trial_expired":false},{"name":"email","enabled":false,"trial_expired":false},{"name":"duo","enabled":false,"trial_expired":false},{"name":"webauthn-roaming","enabled":false,"trial_expired":false},{"name":"webauthn-platform","enabled":false,"trial_expired":false},{"name":"recovery-code","enabled":false,"trial_expired":false}]' headers: Content-Type: - application/json; charset=utf-8 @@ -51,7 +51,7 @@ interactions: url: https://go-auth0-dev.eu.auth0.com/api/v2/guardian/factors method: GET response: - body: '[{"name":"sms","enabled":true,"trial_expired":false},{"name":"push-notification","enabled":false,"trial_expired":false},{"name":"otp","enabled":false,"trial_expired":false},{"name":"email","enabled":false,"trial_expired":false},{"name":"duo","enabled":true,"trial_expired":false},{"name":"webauthn-roaming","enabled":false,"trial_expired":false},{"name":"webauthn-platform","enabled":false,"trial_expired":false},{"name":"recovery-code","enabled":false,"trial_expired":false}]' + body: '[{"name":"sms","enabled":false,"trial_expired":false},{"name":"push-notification","enabled":false,"trial_expired":false},{"name":"otp","enabled":false,"trial_expired":false},{"name":"email","enabled":false,"trial_expired":false},{"name":"duo","enabled":true,"trial_expired":false},{"name":"webauthn-roaming","enabled":false,"trial_expired":false},{"name":"webauthn-platform","enabled":false,"trial_expired":false},{"name":"recovery-code","enabled":false,"trial_expired":false}]' headers: Content-Type: - application/json; charset=utf-8 diff --git a/management/testdata/recordings/TestGuardian/MultiFactor/DUO/Settings.yaml b/management/testdata/recordings/TestGuardian/MultiFactor/DUO/Settings.yaml new file mode 100644 index 00000000..62e3367f --- /dev/null +++ b/management/testdata/recordings/TestGuardian/MultiFactor/DUO/Settings.yaml @@ -0,0 +1,79 @@ +--- +version: 1 +interactions: +- request: + body: | + null + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0-SDK/latest + url: https://go-auth0-dev.eu.auth0.com/api/v2/guardian/factors/duo/settings + method: GET + response: + body: '{"ikey":"asdasdasd","skey":"asdascxzcasd","host":"asdasdaasdas"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 1ms +- request: + body: | + {"host":"api-hostname","ikey":"someKey","skey":"someSecret"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0-SDK/latest + url: https://go-auth0-dev.eu.auth0.com/api/v2/guardian/factors/duo/settings + method: PUT + response: + body: '{"host":"api-hostname","ikey":"someKey","skey":"someSecret"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 1ms +- request: + body: | + null + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0-SDK/latest + url: https://go-auth0-dev.eu.auth0.com/api/v2/guardian/factors/duo/settings + method: GET + response: + body: '{"ikey":"someKey","skey":"someSecret","host":"api-hostname"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 1ms +- request: + body: | + {"host":"asdasdaasdas","ikey":"asdasdasd","skey":"asdascxzcasd"} + form: {} + headers: + Content-Type: + - application/json + User-Agent: + - Go-Auth0-SDK/latest + url: https://go-auth0-dev.eu.auth0.com/api/v2/guardian/factors/duo/settings + method: PUT + response: + body: '{"host":"asdasdaasdas","ikey":"asdasdasd","skey":"asdascxzcasd"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 200 OK + code: 200 + duration: 1ms