Skip to content

Commit

Permalink
misc
Browse files Browse the repository at this point in the history
  • Loading branch information
sjc5 committed Aug 9, 2024
1 parent ed2e98a commit ca6bfc0
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 39 deletions.
12 changes: 7 additions & 5 deletions pkg/bytesutil/bytesutil.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package bytesutil provides utility functions for byte slice operations.
package bytesutil

import (
Expand Down Expand Up @@ -38,18 +39,19 @@ func ToGob(src any) ([]byte, error) {
return a.Bytes(), nil
}

// FromGob decodes a gob-encoded byte slice into an arbitrary value.
func FromGobInto(gobBytes []byte, dest any) error {
// FromGobInto decodes a gob-encoded byte slice into a destination.
// The destination must be a pointer to the destination type.
func FromGobInto(gobBytes []byte, destPtr any) error {
if gobBytes == nil {
return fmt.Errorf("bytesutil.FromGobInto: cannot decode nil bytes")
}
if dest == nil {
if destPtr == nil {
return fmt.Errorf("bytesutil.FromGobInto: cannot decode into nil destination")
}
dec := gob.NewDecoder(bytes.NewReader(gobBytes))
err := dec.Decode(dest)
err := dec.Decode(destPtr)
if err != nil {
return fmt.Errorf("failed to decode bytes into dest: %w", err)
return fmt.Errorf("bytesutil.FromGobInto: failed to decode bytes into dest: %w", err)
}
return nil
}
9 changes: 9 additions & 0 deletions pkg/cryptoutil/cryptoutil.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package cryptoutil provides utility functions for cryptographic operations.
package cryptoutil

import (
Expand All @@ -7,6 +8,8 @@ import (
"golang.org/x/crypto/nacl/sign"
)

// SignSymmetric signs a message using a symmetric key. It is a convenience
// wrapper around the nacl/auth package.
func SignSymmetric(msg []byte, secretKey *[32]byte) ([]byte, error) {
digest := auth.Sum(msg, secretKey)
signedMsg := make([]byte, auth.Size+len(msg))
Expand All @@ -15,6 +18,9 @@ func SignSymmetric(msg []byte, secretKey *[32]byte) ([]byte, error) {
return signedMsg, nil
}

// VerifyAndReadSymmetric verifies a signed message using a symmetric key and
// returns the original message. It is a convenience wrapper around the
// nacl/auth package.
func VerifyAndReadSymmetric(signedMsg []byte, secretKey *[32]byte) ([]byte, error) {
if len(signedMsg) < auth.Size {
return nil, errors.New("invalid signature")
Expand All @@ -28,6 +34,9 @@ func VerifyAndReadSymmetric(signedMsg []byte, secretKey *[32]byte) ([]byte, erro
return msg, nil
}

// VerifyAndReadAssymetric verifies a signed message using a public key and
// returns the original message. It is a convenience wrapper around the
// nacl/sign package.
func VerifyAndReadAssymetric(signedMsg []byte, publicKey *[32]byte) ([]byte, error) {
msg, ok := sign.Open(nil, signedMsg, publicKey)
if !ok {
Expand Down
25 changes: 18 additions & 7 deletions pkg/fsutil/fsutil.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package fsutil provides utility functions for working with the filesystem.
package fsutil

import (
Expand All @@ -10,16 +11,18 @@ import (
"runtime"
)

// EnsureDir creates a directory if it does not exist.
func EnsureDir(path string) error {
return os.MkdirAll(path, os.ModePerm)
}

// GetCallerDir returns the directory of the calling function.
func GetCallerDir() string {
_, file, _, _ := runtime.Caller(1)
return filepath.Dir(file)
}

// copyDir recursively copies a directory from src to dst.
// CopyDir recursively copies a directory from src to dst.
func CopyDir(src, dst string) error {
// Get properties of source dir
info, err := os.Stat(src)
Expand Down Expand Up @@ -62,15 +65,15 @@ func CopyDir(src, dst string) error {
return nil
}

// copyFile copies a single file from src to dst
func CopyFile(src, dst string) error {
// CopyFile copies a single file from src to dest
func CopyFile(src, dest string) error {
sourceFile, err := os.Open(src)
if err != nil {
return err
}
defer sourceFile.Close()

destFile, err := os.Create(dst)
destFile, err := os.Create(dest)
if err != nil {
return err
}
Expand All @@ -82,11 +85,19 @@ func CopyFile(src, dst string) error {
return destFile.Sync()
}

func FromGobInto(file fs.File, dest any) error {
// FromGobInto decodes a gob-encoded file into a destination.
// The destination must be a pointer to the destination type.
func FromGobInto(file fs.File, destPtr any) error {
if file == nil {
return fmt.Errorf("fsutil.FromGobInto: cannot decode nil file")
}
if destPtr == nil {
return fmt.Errorf("fsutil.FromGobInto: cannot decode into nil destination")
}
dec := gob.NewDecoder(file)
err := dec.Decode(dest)
err := dec.Decode(destPtr)
if err != nil {
return fmt.Errorf("failed to decode bytes into dest: %w", err)
return fmt.Errorf("fsutil.FromGobInto: failed to decode file into dest: %w", err)
}
return nil
}
6 changes: 2 additions & 4 deletions pkg/signedcookie/signedcookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import (
/////// CORE SIGNED COOKIES MANAGER
////////////////////////////////////////////////////////////////////

const (
SecretSize = 32 // SecretSize is the size, in bytes, of a cookie secret.
)
const SecretSize = 32 // SecretSize is the size, in bytes, of a cookie secret.

// Manager handles the creation, signing, and verification of secure cookies.
type Manager struct {
Expand Down Expand Up @@ -168,7 +166,7 @@ func (sc *SignedCookie[T]) VerifyAndReadCookieValue(r *http.Request) (*T, error)
return &instance, nil
}

// createSecureCookie creates a new secure cookie with the provided name, expiration, and base settings.
// newSecureCookieWithoutValue creates a new secure cookie with the provided name, expiration, and base settings.
// It ensures that the cookie is marked as HTTP-only and secure.
func newSecureCookieWithoutValue(name string, expires *time.Time, baseCookie BaseCookie) *http.Cookie {
newCookie := http.Cookie{}
Expand Down
9 changes: 5 additions & 4 deletions pkg/validate/search_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
"strings"
)

func parseURLValues(values map[string][]string, dst any) error {
dstValue := reflect.ValueOf(dst)
// ParseURLValues parses URL values into a struct.
func parseURLValues(values map[string][]string, destStructPtr any) error {
dstValue := reflect.ValueOf(destStructPtr)
if dstValue.Kind() != reflect.Ptr || dstValue.IsNil() {
return fmt.Errorf("destination must be a non-nil pointer")
return fmt.Errorf("validate.parseURLValues: destination must be non-nil")
}

dstElem := dstValue.Elem()
Expand All @@ -20,7 +21,7 @@ func parseURLValues(values map[string][]string, dst any) error {
}

if dstElem.Kind() != reflect.Struct {
return fmt.Errorf("destination must be a pointer to a struct")
return fmt.Errorf("validate.parseURLValues: destination must point to a struct")
}

return setNestedField(dstElem, values)
Expand Down
46 changes: 27 additions & 19 deletions pkg/validate/validate.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package validate provides a simple way to validate and parse data from HTTP requests.
package validate

import (
Expand All @@ -9,12 +10,15 @@ import (
"github.com/go-playground/validator/v10"
)

// Validate is a wrapper around the go-playground/validator package.
// It provides methods for validating and parsing data from HTTP requests.
type Validate struct {
Instance *validator.Validate
}

const ValidationErrorPrefix = "validation error: "

// IsValidationError returns true if the error is a validation error.
func IsValidationError(err error) bool {
if err == nil {
return false
Expand All @@ -26,57 +30,61 @@ func IsValidationError(err error) bool {
return errMsg[:len(ValidationErrorPrefix)] == ValidationErrorPrefix
}

func (v Validate) JSONBodyInto(body io.ReadCloser, dest any) error {
if err := json.NewDecoder(body).Decode(dest); err != nil {
// JSONBodyInto decodes the JSON body of an HTTP request into a struct and validates it.
func (v Validate) JSONBodyInto(body io.ReadCloser, destStructPtr any) error {
if err := json.NewDecoder(body).Decode(destStructPtr); err != nil {
return fmt.Errorf("error decoding JSON: %w", err)
}
if err := v.Instance.Struct(dest); err != nil {
if err := v.Instance.Struct(destStructPtr); err != nil {
return fmt.Errorf(ValidationErrorPrefix+"%w", err)
}
return nil
}

func (v Validate) JSONBytesInto(data []byte, dest any) error {
if err := json.Unmarshal(data, dest); err != nil {
// JSONBytesInto decodes a byte slice containing JSON data into a struct and validates it.
func (v Validate) JSONBytesInto(data []byte, destStructPtr any) error {
if err := json.Unmarshal(data, destStructPtr); err != nil {
return fmt.Errorf("error decoding JSON: %w", err)
}
if err := v.Instance.Struct(dest); err != nil {
if err := v.Instance.Struct(destStructPtr); err != nil {
return fmt.Errorf(ValidationErrorPrefix+"%w", err)
}
return nil
}

func (v Validate) JSONStrInto(data string, dest any) error {
return v.UnmarshalFromBytes([]byte(data), dest)
// JSONStrInto decodes a string containing JSON data into a struct and validates it.
func (v Validate) JSONStrInto(data string, destStructPtr any) error {
return v.JSONBytesInto([]byte(data), destStructPtr)
}

func (v Validate) URLSearchParamsInto(r *http.Request, dest any) error {
err := parseURLValues(r.URL.Query(), dest)
// URLSearchParamsInto parses the URL parameters of an HTTP request into a struct and validates it.
func (v Validate) URLSearchParamsInto(r *http.Request, destStructPtr any) error {
err := parseURLValues(r.URL.Query(), destStructPtr)
if err != nil {
return fmt.Errorf("error parsing URL parameters: %w", err)
}
if err := v.Instance.Struct(dest); err != nil {
if err := v.Instance.Struct(destStructPtr); err != nil {
return fmt.Errorf(ValidationErrorPrefix+"%w", err)
}
return nil
}

// Deprecated: UnmarshalFromRequest is deprecated. Use `v.JSONBodyInto(r.Body, dest)` instead.
func (v Validate) UnmarshalFromRequest(r *http.Request, dest any) error {
return v.JSONBodyInto(r.Body, dest)
func (v Validate) UnmarshalFromRequest(r *http.Request, destStructPtr any) error {
return v.JSONBodyInto(r.Body, destStructPtr)
}

// Deprecated: UnmarshalFromBytes is deprecated. Use JSONBytesInto instead.
func (v Validate) UnmarshalFromBytes(data []byte, dest any) error {
return v.JSONBytesInto(data, dest)
func (v Validate) UnmarshalFromBytes(data []byte, destStructPtr any) error {
return v.JSONBytesInto(data, destStructPtr)
}

// Deprecated: UnmarshalFromString is deprecated. Use JSONStrInto instead.
func (v Validate) UnmarshalFromString(data string, dest any) error {
return v.JSONStrInto(data, dest)
func (v Validate) UnmarshalFromString(data string, destStructPtr any) error {
return v.JSONStrInto(data, destStructPtr)
}

// Deprecated: UnmarshalFromResponse is deprecated. Use `v.JSONBodyInto(r.Body, dest)` instead.
func (v Validate) UnmarshalFromResponse(r *http.Response, dest any) error {
return v.JSONBodyInto(r.Body, dest)
func (v Validate) UnmarshalFromResponse(r *http.Response, destStructPtr any) error {
return v.JSONBodyInto(r.Body, destStructPtr)
}

0 comments on commit ca6bfc0

Please sign in to comment.