ory-am/hydra

View on GitHub
x/hasher.go

Summary

Maintainability
A
0 mins
Test Coverage
// Copyright © 2022 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package x

import (
    "context"

    "github.com/ory/fosite"
    "github.com/ory/x/hasherx"

    "go.opentelemetry.io/otel"

    "github.com/ory/x/errorsx"
)

const tracingComponent = "github.com/ory/hydra/x"

var _ fosite.Hasher = (*Hasher)(nil)

type HashAlgorithm string

func (a HashAlgorithm) String() string {
    return string(a)
}

const (
    HashAlgorithmBCrypt = HashAlgorithm("bcrypt")
    HashAlgorithmPBKDF2 = HashAlgorithm("pbkdf2")
)

// Hasher implements fosite.Hasher.
type Hasher struct {
    c      config
    bcrypt *hasherx.Bcrypt
    pbkdf2 *hasherx.PBKDF2
}

type config interface {
    hasherx.PBKDF2Configurator
    hasherx.BCryptConfigurator
    GetHasherAlgorithm(ctx context.Context) HashAlgorithm
}

// NewHasher returns a new BCrypt instance.
func NewHasher(c config) *Hasher {
    return &Hasher{
        c:      c,
        bcrypt: hasherx.NewHasherBcrypt(c),
        pbkdf2: hasherx.NewHasherPBKDF2(c),
    }
}

func (b *Hasher) Hash(ctx context.Context, data []byte) ([]byte, error) {
    ctx, span := otel.GetTracerProvider().Tracer(tracingComponent).Start(ctx, "x.hasher.Hash")
    defer span.End()

    switch b.c.GetHasherAlgorithm(ctx) {
    case HashAlgorithmBCrypt:
        return b.bcrypt.Generate(ctx, data)
    case HashAlgorithmPBKDF2:
        fallthrough
    default:
        return b.pbkdf2.Generate(ctx, data)
    }
}

func (b *Hasher) Compare(ctx context.Context, hash, data []byte) error {
    _, span := otel.GetTracerProvider().Tracer(tracingComponent).Start(ctx, "x.hasher.Hash")
    defer span.End()

    if err := hasherx.Compare(ctx, data, hash); err != nil {
        return errorsx.WithStack(err)
    }
    return nil
}