diff --git a/relay/auth/hmac/v2/generator.go b/relay/auth/hmac/v2/generator.go index 76a68792ae..8275327307 100644 --- a/relay/auth/hmac/v2/generator.go +++ b/relay/auth/hmac/v2/generator.go @@ -10,6 +10,7 @@ import ( type Generator struct { algo func() hash.Hash + algoType AuthAlgo secret []byte timeToLive time.Duration } @@ -21,6 +22,7 @@ func NewGenerator(algo AuthAlgo, secret []byte, timeToLive time.Duration) (*Gene } return &Generator{ algo: algoFunc, + algoType: algo, secret: secret, timeToLive: timeToLive, }, nil @@ -36,6 +38,7 @@ func (g *Generator) GenerateToken() (*Token, error) { signature := h.Sum(nil) return &Token{ + AuthAlgo: g.algoType, Signature: signature, Payload: payload, }, nil diff --git a/relay/auth/hmac/v2/hmac_test.go b/relay/auth/hmac/v2/hmac_test.go new file mode 100644 index 0000000000..40336363fe --- /dev/null +++ b/relay/auth/hmac/v2/hmac_test.go @@ -0,0 +1,110 @@ +package v2 + +import ( + "strconv" + "testing" + "time" +) + +func TestGenerateCredentials(t *testing.T) { + secret := "supersecret" + timeToLive := 1 * time.Hour + g, err := NewGenerator(AuthAlgoHMACSHA256, []byte(secret), timeToLive) + if err != nil { + t.Fatalf("failed to create generator: %v", err) + } + + token, err := g.GenerateToken() + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + if len(token.Payload) == 0 { + t.Fatalf("expected non-empty payload") + } + + _, err = strconv.ParseInt(string(token.Payload), 10, 64) + if err != nil { + t.Fatalf("expected payload to be a valid unix timestamp, got %v", err) + } +} + +func TestValidateCredentials(t *testing.T) { + secret := "supersecret" + timeToLive := 1 * time.Hour + g, err := NewGenerator(AuthAlgoHMACSHA256, []byte(secret), timeToLive) + if err != nil { + t.Fatalf("failed to create generator: %v", err) + } + + token, err := g.GenerateToken() + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + v := NewValidator([]byte(secret)) + if err := v.Validate(token.Marshal()); err != nil { + t.Fatalf("expected valid token: %s", err) + } +} + +func TestInvalidSignature(t *testing.T) { + secret := "supersecret" + timeToLive := 1 * time.Hour + g, err := NewGenerator(AuthAlgoHMACSHA256, []byte(secret), timeToLive) + if err != nil { + t.Fatalf("failed to create generator: %v", err) + } + + token, err := g.GenerateToken() + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + token.Signature = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + + v := NewValidator([]byte(secret)) + if err := v.Validate(token.Marshal()); err == nil { + t.Fatalf("expected valid token: %s", err) + } +} + +func TestExpired(t *testing.T) { + secret := "supersecret" + timeToLive := -1 * time.Hour + g, err := NewGenerator(AuthAlgoHMACSHA256, []byte(secret), timeToLive) + if err != nil { + t.Fatalf("failed to create generator: %v", err) + } + + token, err := g.GenerateToken() + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + v := NewValidator([]byte(secret)) + if err := v.Validate(token.Marshal()); err == nil { + t.Fatalf("expected valid token: %s", err) + } +} + +func TestInvalidPayload(t *testing.T) { + secret := "supersecret" + timeToLive := 1 * time.Hour + g, err := NewGenerator(AuthAlgoHMACSHA256, []byte(secret), timeToLive) + if err != nil { + t.Fatalf("failed to create generator: %v", err) + } + + token, err := g.GenerateToken() + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + + token.Payload = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + + v := NewValidator([]byte(secret)) + if err := v.Validate(token.Marshal()); err == nil { + t.Fatalf("expected invalid token due to invalid payload") + } +}