mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-18 18:38:08 -05:00
Co-authored-by: Chris-Paris-HashiCorp <chris.paris@hashicorp.com>
This commit is contained in:
parent
7c5d32dcc1
commit
521997a16f
5 changed files with 344 additions and 90 deletions
|
|
@ -15,10 +15,12 @@ import (
|
|||
|
||||
"github.com/hashicorp/vault/helper/namespace"
|
||||
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
|
||||
"github.com/hashicorp/vault/sdk/helper/testhelpers/observations"
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
otplib "github.com/pquerna/otp"
|
||||
totplib "github.com/pquerna/otp/totp"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func createKey() (string, error) {
|
||||
|
|
@ -45,6 +47,8 @@ func generateCode(key string, period uint, digits otplib.Digits, algorithm otpli
|
|||
|
||||
func TestBackend_KeyName(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -84,7 +88,7 @@ func TestBackend_KeyName(t *testing.T) {
|
|||
}
|
||||
var resp *logical.Response
|
||||
for _, tc := range tests {
|
||||
resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
|
||||
req := &logical.Request{
|
||||
Path: "keys/" + tc.KeyName,
|
||||
Operation: logical.UpdateOperation,
|
||||
Storage: config.StorageView,
|
||||
|
|
@ -93,7 +97,8 @@ func TestBackend_KeyName(t *testing.T) {
|
|||
"account_name": "vault",
|
||||
"issuer": "hashicorp",
|
||||
},
|
||||
})
|
||||
}
|
||||
resp, err = b.HandleRequest(namespace.RootContext(nil), req)
|
||||
if tc.Fail {
|
||||
if err == nil {
|
||||
t.Fatalf("expected an error for test %q", tc.Name)
|
||||
|
|
@ -102,22 +107,62 @@ func TestBackend_KeyName(t *testing.T) {
|
|||
} else if err != nil || (resp != nil && resp.IsError()) {
|
||||
t.Fatalf("bad: test name: %q\nresp: %#v\nerr: %v", tc.Name, resp, err)
|
||||
}
|
||||
resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
|
||||
lastObservation := obsRecorder.LastObservationOfType(ObservationTypeTOTPKeyCreate)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsRequestID, ok := lastObservation.Data["request_id"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing request_id")
|
||||
}
|
||||
if obsRequestID != req.ID {
|
||||
t.Fatalf("observation request_id %q does not equal req.ID %q", obsRequestID, req.ID)
|
||||
}
|
||||
obsKeyName, ok := lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != tc.KeyName {
|
||||
t.Fatalf("observation key_name %q != test KeyName %q", obsKeyName, tc.KeyName)
|
||||
}
|
||||
|
||||
req = &logical.Request{
|
||||
Path: "code/" + tc.KeyName,
|
||||
Operation: logical.ReadOperation,
|
||||
Storage: config.StorageView,
|
||||
})
|
||||
}
|
||||
resp, err = b.HandleRequest(namespace.RootContext(nil), req)
|
||||
if err != nil || (resp != nil && resp.IsError()) {
|
||||
t.Fatalf("bad: test name: %q\nresp: %#v\nerr: %v", tc.Name, resp, err)
|
||||
}
|
||||
if resp.Data["code"].(string) == "" {
|
||||
t.Fatalf("failed to generate code for test %q", tc.Name)
|
||||
}
|
||||
lastObservation = obsRecorder.LastObservationOfType(ObservationTypeTOTPCodeGenerate)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsRequestID, ok = lastObservation.Data["request_id"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing request_id")
|
||||
}
|
||||
if obsRequestID != req.ID {
|
||||
t.Fatalf("observation request_id %q does not equal req.ID %q", obsRequestID, req.ID)
|
||||
}
|
||||
obsKeyName, ok = lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != tc.KeyName {
|
||||
t.Fatalf("observation key_name %q != test KeyName %q", obsKeyName, tc.KeyName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackend_readCredentialsDefaultValues(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -144,15 +189,17 @@ func TestBackend_readCredentialsDefaultValues(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_readCredentialsEightDigitsThirtySecondPeriod(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -182,15 +229,17 @@ func TestBackend_readCredentialsEightDigitsThirtySecondPeriod(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_readCredentialsSixDigitsNinetySecondPeriod(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -220,15 +269,17 @@ func TestBackend_readCredentialsSixDigitsNinetySecondPeriod(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_readCredentialsSHA256(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -258,15 +309,17 @@ func TestBackend_readCredentialsSHA256(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_readCredentialsSHA512(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -296,15 +349,17 @@ func TestBackend_readCredentialsSHA512(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_keyCrudDefaultValues(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -335,22 +390,24 @@ func TestBackend_keyCrudDefaultValues(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepValidateCode(t, "test", code, true, false),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepValidateCode(t, "test", code, true, false, obsRecorder),
|
||||
// Next step should fail because it should be in the used cache
|
||||
testAccStepValidateCode(t, "test", code+" ", false, true),
|
||||
testAccStepValidateCode(t, "test", " "+code, false, true),
|
||||
testAccStepValidateCode(t, "test", code, false, true),
|
||||
testAccStepValidateCode(t, "test", invalidCode, false, false),
|
||||
testAccStepDeleteKey(t, "test"),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepValidateCode(t, "test", code+" ", false, true, obsRecorder),
|
||||
testAccStepValidateCode(t, "test", " "+code, false, true, obsRecorder),
|
||||
testAccStepValidateCode(t, "test", code, false, true, obsRecorder),
|
||||
testAccStepValidateCode(t, "test", invalidCode, false, false, obsRecorder),
|
||||
testAccStepDeleteKey(t, "test", obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_createKeyMissingKeyValue(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -366,14 +423,16 @@ func TestBackend_createKeyMissingKeyValue(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_createKeyInvalidKeyValue(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -390,14 +449,16 @@ func TestBackend_createKeyInvalidKeyValue(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_createKeyInvalidAlgorithm(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -418,14 +479,16 @@ func TestBackend_createKeyInvalidAlgorithm(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_createKeyInvalidPeriod(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -446,14 +509,16 @@ func TestBackend_createKeyInvalidPeriod(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_createKeyInvalidDigits(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -474,14 +539,16 @@ func TestBackend_createKeyInvalidDigits(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyDefaultValues(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -508,14 +575,16 @@ func TestBackend_generatedKeyDefaultValues(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyDefaultValuesNoQR(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -534,13 +603,15 @@ func TestBackend_generatedKeyDefaultValuesNoQR(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyNonDefaultKeySize(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -567,14 +638,16 @@ func TestBackend_generatedKeyNonDefaultKeySize(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyInvalidPeriod(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -591,14 +664,16 @@ func TestBackend_urlPassedNonGeneratedKeyInvalidPeriod(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyInvalidDigits(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -615,14 +690,16 @@ func TestBackend_urlPassedNonGeneratedKeyInvalidDigits(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyIssuerInFirstPosition(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -648,15 +725,17 @@ func TestBackend_urlPassedNonGeneratedKeyIssuerInFirstPosition(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyIssuerInQueryString(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -682,15 +761,17 @@ func TestBackend_urlPassedNonGeneratedKeyIssuerInQueryString(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyMissingIssuer(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -716,15 +797,17 @@ func TestBackend_urlPassedNonGeneratedKeyMissingIssuer(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyMissingAccountName(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -750,9 +833,9 @@ func TestBackend_urlPassedNonGeneratedKeyMissingAccountName(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -760,6 +843,8 @@ func TestBackend_urlPassedNonGeneratedKeyMissingAccountName(t *testing.T) {
|
|||
func TestBackend_urlPassedNonGeneratedKeyMissingAccountNameandIssuer(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -784,15 +869,17 @@ func TestBackend_urlPassedNonGeneratedKeyMissingAccountNameandIssuer(t *testing.
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlPassedNonGeneratedKeyMissingAccountNameandIssuerandPadding(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -818,15 +905,17 @@ func TestBackend_urlPassedNonGeneratedKeyMissingAccountNameandIssuerandPadding(t
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
testAccStepReadCreds(t, b, config.StorageView, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyInvalidSkew(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -843,14 +932,16 @@ func TestBackend_generatedKeyInvalidSkew(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyInvalidQRSize(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -867,14 +958,16 @@ func TestBackend_generatedKeyInvalidQRSize(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyInvalidKeySize(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -891,14 +984,16 @@ func TestBackend_generatedKeyInvalidKeySize(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyMissingAccountName(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -913,14 +1008,16 @@ func TestBackend_generatedKeyMissingAccountName(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyMissingIssuer(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -935,14 +1032,16 @@ func TestBackend_generatedKeyMissingIssuer(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_invalidURLValue(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -957,14 +1056,16 @@ func TestBackend_invalidURLValue(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_urlAndGenerateTrue(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -979,14 +1080,16 @@ func TestBackend_urlAndGenerateTrue(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_keyAndGenerateTrue(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -1001,14 +1104,16 @@ func TestBackend_keyAndGenerateTrue(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, true),
|
||||
testAccStepReadKey(t, "test", nil),
|
||||
testAccStepCreateKey(t, "test", keyData, true, obsRecorder),
|
||||
testAccStepReadKey(t, "test", nil, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_generatedKeyExportedFalse(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
obsRecorder := observations.NewTestObservationRecorder()
|
||||
config.ObservationRecorder = obsRecorder
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
b, err := Factory(context.Background(), config)
|
||||
if err != nil {
|
||||
|
|
@ -1033,18 +1138,22 @@ func TestBackend_generatedKeyExportedFalse(t *testing.T) {
|
|||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
LogicalBackend: b,
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepCreateKey(t, "test", keyData, false),
|
||||
testAccStepReadKey(t, "test", expected),
|
||||
testAccStepCreateKey(t, "test", keyData, false, obsRecorder),
|
||||
testAccStepReadKey(t, "test", expected, obsRecorder),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccStepCreateKey(t *testing.T, name string, keyData map[string]interface{}, expectFail bool) logicaltest.TestStep {
|
||||
func testAccStepCreateKey(t *testing.T, name string, keyData map[string]interface{}, expectFail bool, obsRecorder *observations.TestObservationRecorder) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.UpdateOperation,
|
||||
Path: path.Join("keys", name),
|
||||
Data: keyData,
|
||||
ErrorOk: expectFail,
|
||||
PreFlight: func(req *logical.Request) error {
|
||||
obsRecorder.Reset()
|
||||
return nil
|
||||
},
|
||||
Check: func(resp *logical.Response) error {
|
||||
// Skip this if the key is not generated by vault or if the test is expected to fail
|
||||
if !keyData["generate"].(bool) || expectFail {
|
||||
|
|
@ -1106,22 +1215,56 @@ func testAccStepCreateKey(t *testing.T, name string, keyData map[string]interfac
|
|||
t.Fatal("incorrect key string length")
|
||||
}
|
||||
|
||||
lastObservation := obsRecorder.LastObservationOfType(ObservationTypeTOTPKeyCreate)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsKeyName, ok := lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != name {
|
||||
t.Fatalf("observation key_name %q != test name %q", obsKeyName, name)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepDeleteKey(t *testing.T, name string) logicaltest.TestStep {
|
||||
func testAccStepDeleteKey(t *testing.T, name string, obsRecorder *observations.TestObservationRecorder) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.DeleteOperation,
|
||||
Path: path.Join("keys", name),
|
||||
PreFlight: func(req *logical.Request) error {
|
||||
obsRecorder.Reset()
|
||||
return nil
|
||||
},
|
||||
Check: func(resp *logical.Response) error {
|
||||
lastObservation := obsRecorder.LastObservationOfType(ObservationTypeTOTPKeyDelete)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsKeyName, ok := lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != name {
|
||||
t.Fatalf("observation key_name %q != test name %q", obsKeyName, name)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepReadCreds(t *testing.T, b logical.Backend, s logical.Storage, name string, validation map[string]interface{}) logicaltest.TestStep {
|
||||
func testAccStepReadCreds(t *testing.T, b logical.Backend, s logical.Storage, name string, validation map[string]interface{}, obsRecorder *observations.TestObservationRecorder) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: path.Join("code", name),
|
||||
PreFlight: func(req *logical.Request) error {
|
||||
obsRecorder.Reset()
|
||||
return nil
|
||||
},
|
||||
Check: func(resp *logical.Response) error {
|
||||
var d struct {
|
||||
Code string `mapstructure:"code"`
|
||||
|
|
@ -1149,15 +1292,35 @@ func testAccStepReadCreds(t *testing.T, b logical.Backend, s logical.Storage, na
|
|||
t.Fatalf("generated code isn't valid")
|
||||
}
|
||||
|
||||
lastObservation := obsRecorder.LastObservationOfType(ObservationTypeTOTPCodeGenerate)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsKeyName, ok := lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != name {
|
||||
t.Fatalf("observation key_name %q != test name %q", obsKeyName, name)
|
||||
}
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyRead))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyCreate))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyDelete))
|
||||
require.Equal(t, 1, obsRecorder.NumObservationsByType(ObservationTypeTOTPCodeGenerate))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPCodeValidate))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepReadKey(t *testing.T, name string, expected map[string]interface{}) logicaltest.TestStep {
|
||||
func testAccStepReadKey(t *testing.T, name string, expected map[string]interface{}, obsRecorder *observations.TestObservationRecorder) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: "keys/" + name,
|
||||
PreFlight: func(req *logical.Request) error {
|
||||
obsRecorder.Reset()
|
||||
return nil
|
||||
},
|
||||
Check: func(resp *logical.Response) error {
|
||||
if resp == nil {
|
||||
if expected == nil {
|
||||
|
|
@ -1202,12 +1365,30 @@ func testAccStepReadKey(t *testing.T, name string, expected map[string]interface
|
|||
case d.Digits != expected["digits"]:
|
||||
return fmt.Errorf("digits should equal: %d", expected["digits"])
|
||||
}
|
||||
|
||||
lastObservation := obsRecorder.LastObservationOfType(ObservationTypeTOTPKeyRead)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsKeyName, ok := lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != name {
|
||||
t.Fatalf("observation key_name %q != test name %q", obsKeyName, name)
|
||||
}
|
||||
require.Equal(t, 1, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyRead))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyCreate))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyDelete))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPCodeGenerate))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPCodeValidate))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepValidateCode(t *testing.T, name string, code string, valid, expectError bool) logicaltest.TestStep {
|
||||
func testAccStepValidateCode(t *testing.T, name string, code string, valid, expectError bool, obsRecorder *observations.TestObservationRecorder) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.UpdateOperation,
|
||||
Path: "code/" + name,
|
||||
|
|
@ -1215,6 +1396,10 @@ func testAccStepValidateCode(t *testing.T, name string, code string, valid, expe
|
|||
"code": code,
|
||||
},
|
||||
ErrorOk: expectError,
|
||||
PreFlight: func(req *logical.Request) error {
|
||||
obsRecorder.Reset()
|
||||
return nil
|
||||
},
|
||||
Check: func(resp *logical.Response) error {
|
||||
if resp == nil {
|
||||
return fmt.Errorf("bad: %#v", resp)
|
||||
|
|
@ -1233,6 +1418,22 @@ func testAccStepValidateCode(t *testing.T, name string, code string, valid, expe
|
|||
if d.Valid != true {
|
||||
return fmt.Errorf("code was not valid: %s", code)
|
||||
}
|
||||
lastObservation := obsRecorder.LastObservationOfType(ObservationTypeTOTPCodeValidate)
|
||||
if lastObservation == nil {
|
||||
t.Fatal("missing observation")
|
||||
}
|
||||
obsKeyName, ok := lastObservation.Data["key_name"]
|
||||
if !ok {
|
||||
t.Fatal("observation is missing key_name")
|
||||
}
|
||||
if obsKeyName != name {
|
||||
t.Fatalf("observation key_name %q != test name %q", obsKeyName, name)
|
||||
}
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyRead))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyCreate))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPKeyDelete))
|
||||
require.Equal(t, 0, obsRecorder.NumObservationsByType(ObservationTypeTOTPCodeGenerate))
|
||||
require.Equal(t, 1, obsRecorder.NumObservationsByType(ObservationTypeTOTPCodeValidate))
|
||||
|
||||
default:
|
||||
if d.Valid != false {
|
||||
|
|
|
|||
12
builtin/logical/totp/observation_consts.go
Normal file
12
builtin/logical/totp/observation_consts.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright IBM Corp. 2016, 2025
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package totp
|
||||
|
||||
const (
|
||||
ObservationTypeTOTPKeyRead = "totp/key/read"
|
||||
ObservationTypeTOTPKeyCreate = "totp/key/create"
|
||||
ObservationTypeTOTPKeyDelete = "totp/key/delete"
|
||||
ObservationTypeTOTPCodeGenerate = "totp/code/generate"
|
||||
ObservationTypeTOTPCodeValidate = "totp/code/validate"
|
||||
)
|
||||
|
|
@ -77,6 +77,10 @@ func (b *backend) pathReadCode(ctx context.Context, req *logical.Request, data *
|
|||
return nil, err
|
||||
}
|
||||
|
||||
b.TryRecordObservationWithRequest(ctx, req, ObservationTypeTOTPCodeGenerate, map[string]interface{}{
|
||||
"key_name": name,
|
||||
})
|
||||
|
||||
// Return the secret
|
||||
return &logical.Response{
|
||||
Data: map[string]interface{}{
|
||||
|
|
@ -120,6 +124,11 @@ func (b *backend) pathValidateCode(ctx context.Context, req *logical.Request, da
|
|||
return logical.ErrorResponse("an error occurred while validating the code"), err
|
||||
}
|
||||
|
||||
b.TryRecordObservationWithRequest(ctx, req, ObservationTypeTOTPCodeValidate, map[string]interface{}{
|
||||
"key_name": name,
|
||||
"valid": valid,
|
||||
})
|
||||
|
||||
// Take the key skew, add two for behind and in front, and multiple that by
|
||||
// the period to cover the full possibility of the validity of the key
|
||||
err = b.usedCodes.Add(usedName, nil, time.Duration(
|
||||
|
|
|
|||
|
|
@ -166,16 +166,22 @@ func (b *backend) Key(ctx context.Context, s logical.Storage, n string) (*keyEnt
|
|||
}
|
||||
|
||||
func (b *backend) pathKeyDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
err := req.Storage.Delete(ctx, "key/"+data.Get("name").(string))
|
||||
name := data.Get("name").(string)
|
||||
err := req.Storage.Delete(ctx, "key/"+name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.TryRecordObservationWithRequest(ctx, req, ObservationTypeTOTPKeyDelete, map[string]interface{}{
|
||||
"key_name": name,
|
||||
})
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *backend) pathKeyRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
key, err := b.Key(ctx, req.Storage, data.Get("name").(string))
|
||||
name := data.Get("name").(string)
|
||||
key, err := b.Key(ctx, req.Storage, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -186,6 +192,14 @@ func (b *backend) pathKeyRead(ctx context.Context, req *logical.Request, data *f
|
|||
// Translate algorithm back to string
|
||||
algorithm := key.Algorithm.String()
|
||||
|
||||
b.TryRecordObservationWithRequest(ctx, req, ObservationTypeTOTPKeyRead, map[string]interface{}{
|
||||
"key_name": name,
|
||||
"period": key.Period,
|
||||
"algorithm": algorithm,
|
||||
"digits": key.Digits,
|
||||
"skew": key.Skew,
|
||||
})
|
||||
|
||||
// Return values of key
|
||||
return &logical.Response{
|
||||
Data: map[string]interface{}{
|
||||
|
|
@ -432,6 +446,17 @@ func (b *backend) pathKeyCreate(ctx context.Context, req *logical.Request, data
|
|||
return nil, err
|
||||
}
|
||||
|
||||
b.TryRecordObservationWithRequest(ctx, req, ObservationTypeTOTPKeyCreate, map[string]interface{}{
|
||||
"key_name": name,
|
||||
"period": period,
|
||||
"algorithm": algorithm,
|
||||
"digits": digits,
|
||||
"skew": skew,
|
||||
"generate": generate,
|
||||
"exported": exported,
|
||||
"key_size": keySize,
|
||||
})
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,3 +75,10 @@ func (t *TestObservationRecorder) LastObservationOfType(observationType string)
|
|||
}
|
||||
return ofType[len(ofType)-1]
|
||||
}
|
||||
|
||||
// Reset empties the list of recorded observations.
|
||||
func (t *TestObservationRecorder) Reset() {
|
||||
t.l.Lock()
|
||||
defer t.l.Unlock()
|
||||
t.observationsByType = make(map[string][]*TestObservation)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue