52 lines
1.2 KiB
Go
52 lines
1.2 KiB
Go
package testkit
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"crypto/subtle"
|
|
"errors"
|
|
"strings"
|
|
|
|
"galaxy/authsession/internal/ports"
|
|
)
|
|
|
|
// DeterministicCodeHasher is a deterministic CodeHasher double backed by
|
|
// SHA-256 for test stability.
|
|
type DeterministicCodeHasher struct{}
|
|
|
|
// Hash returns the SHA-256 digest of code.
|
|
func (DeterministicCodeHasher) Hash(code string) ([]byte, error) {
|
|
if err := validateCode(code); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sum := sha256.Sum256([]byte(code))
|
|
return sum[:], nil
|
|
}
|
|
|
|
// Compare reports whether hash equals the deterministic hash of code.
|
|
func (h DeterministicCodeHasher) Compare(hash []byte, code string) (bool, error) {
|
|
if err := validateCode(code); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
expected, err := h.Hash(code)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return subtle.ConstantTimeCompare(hash, expected) == 1, nil
|
|
}
|
|
|
|
var _ ports.CodeHasher = DeterministicCodeHasher{}
|
|
|
|
func validateCode(code string) error {
|
|
switch {
|
|
case strings.TrimSpace(code) == "":
|
|
return errors.New("code must not be empty")
|
|
case strings.TrimSpace(code) != code:
|
|
return errors.New("code must not contain surrounding whitespace")
|
|
default:
|
|
return nil
|
|
}
|
|
}
|