Files
pocket-id/backend/internal/oidc/client_secret_hasher_test.go
T

100 lines
2.4 KiB
Go

package oidc
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt"
"github.com/pocket-id/pocket-id/backend/internal/model"
"github.com/pocket-id/pocket-id/backend/internal/utils"
)
func TestClientSecretHasherCompare(t *testing.T) {
const value = "client-secret-value"
bcryptHash, err := bcrypt.GenerateFromPassword([]byte(value), bcrypt.MinCost)
require.NoError(t, err)
for _, test := range []struct {
name string
hash string
data string
wantErr bool
}{
{
name: "matching SHA-256 hash",
hash: "sha256:" + utils.CreateSha256Hash(value),
data: value,
},
{
name: "SHA-256 hash of another secret",
hash: "sha256:" + utils.CreateSha256Hash(value),
data: "some-other-value",
wantErr: true,
},
{
name: "bcrypt hash migrated from the single-secret column",
hash: "bcrypt:" + string(bcryptHash),
data: value,
},
{
name: "bcrypt hash of another secret",
hash: "bcrypt:" + string(bcryptHash),
data: "some-other-value",
wantErr: true,
},
{
name: "hash without an algorithm",
hash: utils.CreateSha256Hash(value),
data: value,
wantErr: true,
},
{
name: "unknown algorithm",
hash: "md5:" + utils.CreateSha256Hash(value),
data: value,
wantErr: true,
},
{
name: "empty hash, as returned for a client without secrets",
hash: "",
data: value,
wantErr: true,
},
} {
t.Run(test.name, func(t *testing.T) {
err := clientSecretHasher{}.Compare(t.Context(), []byte(test.hash), []byte(test.data))
if test.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestClientSecretHasherHash(t *testing.T) {
const value = "client-secret-value"
hash, err := clientSecretHasher{}.Hash(t.Context(), []byte(value))
require.NoError(t, err)
assert.Equal(t, "sha256:"+utils.CreateSha256Hash(value), string(hash))
// A hash produced by the hasher is accepted by its own comparison
err = clientSecretHasher{}.Compare(t.Context(), hash, []byte(value))
require.NoError(t, err)
}
func TestClientSecretHasherAcceptsModelEncoding(t *testing.T) {
const value = "client-secret-value"
secret := model.OidcClientSecret{
Algorithm: model.OidcClientSecretHashSHA256,
Hash: utils.CreateSha256Hash(value),
}
err := clientSecretHasher{}.Compare(t.Context(), secret.EncodedHash(), []byte(value))
require.NoError(t, err)
}