auth/internal/domain/code.go

64 lines
1.3 KiB
Go

//nolint: gosec
package domain
import (
"encoding/base64"
"testing"
"github.com/brianvoe/gofakeit/v6"
"github.com/stretchr/testify/require"
"source.toby3d.me/website/indieauth/internal/random"
)
// Code describes the PKCE challenge to validate the security of the request.
type Code struct {
Method CodeChallengeMethod
Verifier string
Challenge string
}
const (
CodeLengthMin int = 43
CodeLengthMax int = 128
)
// TestCode returns valid random generated PKCE code for tests.
func TestCode(tb testing.TB) *Code {
tb.Helper()
verifier, err := random.String(
gofakeit.Number(CodeLengthMin, CodeLengthMax), random.Alphanumeric, "-", ".", "_", "~",
)
require.NoError(tb, err)
h := CodeChallengeMethodS256.hash
h.Reset()
_, err = h.Write([]byte(verifier))
require.NoError(tb, err)
return &Code{
Method: CodeChallengeMethodS256,
Verifier: verifier,
Challenge: base64.RawURLEncoding.EncodeToString(h.Sum(nil)),
}
}
// IsValid returns true if code challenge is equal to the generated hash from
// the verifier.
func (c Code) IsValid() bool {
if c.Method == CodeChallengeMethodUndefined {
return false
}
if c.Method == CodeChallengeMethodPLAIN {
return c.Challenge == c.Verifier
}
h := c.Method.hash
h.Reset()
return c.Challenge == base64.RawURLEncoding.EncodeToString(h.Sum([]byte(c.Verifier)))
}