From a9e0d6693d7eec8e3fddfdcccc8fd8482ab65301 Mon Sep 17 00:00:00 2001 From: Johan Brandhorst-Satzkorn Date: Wed, 6 Dec 2023 12:08:30 -0800 Subject: [PATCH] internal/credential/static: simplify list parsing (#4112) Using a struct for the list parsing simplifies the logic and makes the mapping between the result and the Go type safer. --- internal/credential/static/credential.go | 99 +++++++++++++++++++ .../static/repository_credential.go | 94 ++---------------- 2 files changed, 107 insertions(+), 86 deletions(-) create mode 100644 internal/credential/static/credential.go diff --git a/internal/credential/static/credential.go b/internal/credential/static/credential.go new file mode 100644 index 0000000000..1ba4952a90 --- /dev/null +++ b/internal/credential/static/credential.go @@ -0,0 +1,99 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package static + +import ( + "context" + "fmt" + + "github.com/hashicorp/boundary/internal/credential" + "github.com/hashicorp/boundary/internal/credential/static/store" + "github.com/hashicorp/boundary/internal/db/timestamp" + "github.com/hashicorp/boundary/internal/errors" +) + +// listCredentialResult represents the result of the +// list queries used to list all credentials. +type listCredentialResult struct { + PublicId string + StoreId string + ProjectId string + Name string + Description string + Username string + KeyId string + Hmac1 string + Hmac2 string + CreateTime *timestamp.Timestamp + UpdateTime *timestamp.Timestamp + Version int + Type string +} + +func (c *listCredentialResult) toCredential(ctx context.Context) (credential.Static, error) { + const op = "vault.(*listCredentialLibraryResult).toCredential" + switch c.Type { + case "json": + cred := &JsonCredential{ + JsonCredential: &store.JsonCredential{ + PublicId: c.PublicId, + StoreId: c.StoreId, + Name: c.Name, + Description: c.Description, + CreateTime: c.CreateTime, + UpdateTime: c.UpdateTime, + Version: uint32(c.Version), + KeyId: c.KeyId, + }, + } + // Assign byte slices only if the string isn't empty + if c.Hmac1 != "" { + cred.ObjectHmac = []byte(c.Hmac1) + } + return cred, nil + case "upw": + cred := &UsernamePasswordCredential{ + UsernamePasswordCredential: &store.UsernamePasswordCredential{ + PublicId: c.PublicId, + StoreId: c.StoreId, + Name: c.Name, + Description: c.Description, + CreateTime: c.CreateTime, + UpdateTime: c.UpdateTime, + Version: uint32(c.Version), + Username: c.Username, + KeyId: c.KeyId, + }, + } + // Assign byte slices only if the string isn't empty + if c.Hmac1 != "" { + cred.PasswordHmac = []byte(c.Hmac1) + } + return cred, nil + case "ssh": + cred := &SshPrivateKeyCredential{ + SshPrivateKeyCredential: &store.SshPrivateKeyCredential{ + PublicId: c.PublicId, + StoreId: c.StoreId, + Name: c.Name, + Description: c.Description, + CreateTime: c.CreateTime, + UpdateTime: c.UpdateTime, + Version: uint32(c.Version), + Username: c.Username, + KeyId: c.KeyId, + }, + } + // Assign byte slices only if the string isn't empty + if c.Hmac1 != "" { + cred.PrivateKeyHmac = []byte(c.Hmac1) + } + if c.Hmac2 != "" { + cred.PrivateKeyPassphraseHmac = []byte(c.Hmac2) + } + return cred, nil + default: + return nil, errors.New(ctx, errors.Internal, op, fmt.Sprintf("unexpected static credential type %s returned", c.Type)) + } +} diff --git a/internal/credential/static/repository_credential.go b/internal/credential/static/repository_credential.go index 29551bff08..40ebf26faf 100644 --- a/internal/credential/static/repository_credential.go +++ b/internal/credential/static/repository_credential.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/boundary/globals" "github.com/hashicorp/boundary/internal/credential" - "github.com/hashicorp/boundary/internal/credential/static/store" "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db/timestamp" "github.com/hashicorp/boundary/internal/errors" @@ -821,95 +820,18 @@ func (r *Repository) queryCredentials(ctx context.Context, query string, args [] if err != nil { return errors.Wrap(ctx, err, op) } - defer rows.Close() + var results []listCredentialResult for rows.Next() { - var ( - publicId, storeId, projectId, name, description, - username, keyId, hmac1, hmac2 sql.NullString - createTime, updateTime *timestamp.Timestamp - version sql.NullInt64 - typ string - ) - if err := rows.Scan( - &publicId, - &storeId, - &projectId, - &name, - &description, - &createTime, - &updateTime, - &version, - &username, - &keyId, - &hmac1, - &hmac2, - &typ, - ); err != nil { + if err := rd.ScanRows(ctx, rows, &results); err != nil { return errors.Wrap(ctx, err, op) } - switch typ { - case "json": - cred := &JsonCredential{ - JsonCredential: &store.JsonCredential{ - PublicId: publicId.String, - StoreId: storeId.String, - Name: name.String, - Description: description.String, - CreateTime: createTime, - UpdateTime: updateTime, - Version: uint32(version.Int64), - KeyId: keyId.String, - }, - } - // Assign byte slices only if the string isn't empty - if hmac1.String != "" { - cred.ObjectHmac = []byte(hmac1.String) - } - creds = append(creds, cred) - case "upw": - cred := &UsernamePasswordCredential{ - UsernamePasswordCredential: &store.UsernamePasswordCredential{ - PublicId: publicId.String, - StoreId: storeId.String, - Name: name.String, - Description: description.String, - CreateTime: createTime, - UpdateTime: updateTime, - Version: uint32(version.Int64), - Username: username.String, - KeyId: keyId.String, - }, - } - // Assign byte slices only if the string isn't empty - if hmac1.String != "" { - cred.PasswordHmac = []byte(hmac1.String) - } - creds = append(creds, cred) - case "ssh": - cred := &SshPrivateKeyCredential{ - SshPrivateKeyCredential: &store.SshPrivateKeyCredential{ - PublicId: publicId.String, - StoreId: storeId.String, - Name: name.String, - Description: description.String, - CreateTime: createTime, - UpdateTime: updateTime, - Version: uint32(version.Int64), - Username: username.String, - KeyId: keyId.String, - }, - } - // Assign byte slices only if the string isn't empty - if hmac1.String != "" { - cred.PrivateKeyHmac = []byte(hmac1.String) - } - if hmac2.String != "" { - cred.PrivateKeyPassphraseHmac = []byte(hmac2.String) - } - creds = append(creds, cred) - default: - return errors.New(ctx, errors.Internal, op, fmt.Sprintf("unexpected static credential type %s returned", typ)) + } + for _, result := range results { + cred, err := result.toCredential(ctx) + if err != nil { + return errors.Wrap(ctx, err, op) } + creds = append(creds, cred) } transactionTimestamp, err = rd.Now(ctx) return err