68 lines
2.4 KiB
Go
68 lines
2.4 KiB
Go
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package oidcclientsecretstorage
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"time"
|
|
|
|
v1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
|
|
|
"go.pinniped.dev/internal/constable"
|
|
"go.pinniped.dev/internal/crud"
|
|
)
|
|
|
|
const (
|
|
TypeLabelValue = "oidc-client-secret"
|
|
|
|
ErrOIDCClientSecretStorageVersion = constable.Error("OIDC client secret storage data has wrong version")
|
|
|
|
oidcClientSecretStorageVersion = "1"
|
|
)
|
|
|
|
type OIDCClientSecretStorage struct {
|
|
storage crud.Storage
|
|
}
|
|
|
|
// StoredClientSecret defines the format of the content of a client's secrets when stored in a Secret
|
|
// as a JSON string value.
|
|
type StoredClientSecret struct {
|
|
// List of bcrypt hashes.
|
|
SecretHashes []string `json:"hashes"`
|
|
// The format version. Take care when updating. We cannot simply bump the storage version and drop/ignore old data.
|
|
// Updating this would require some form of migration of existing stored data.
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
func New(secrets corev1client.SecretInterface, clock func() time.Time) *OIDCClientSecretStorage {
|
|
// TODO make lifetime = 0 mean that it does not get annotated with any garbage collection annotation
|
|
return &OIDCClientSecretStorage{storage: crud.New(TypeLabelValue, secrets, clock, 0)}
|
|
}
|
|
|
|
// TODO expose other methods as needed for get, create, update, etc.
|
|
|
|
// GetName returns the name of the Secret which would be used to store data for the given signature.
|
|
func (s *OIDCClientSecretStorage) GetName(oidcClientUID types.UID) string {
|
|
// Avoid having s.storage.GetName() base64 decode something that wasn't ever encoded by encoding it here.
|
|
b64encodedUID := base64.RawURLEncoding.EncodeToString([]byte(oidcClientUID))
|
|
return s.storage.GetName(b64encodedUID)
|
|
}
|
|
|
|
// ReadFromSecret reads the contents of a Secret as a StoredClientSecret.
|
|
func ReadFromSecret(secret *v1.Secret) (*StoredClientSecret, error) {
|
|
storedClientSecret := &StoredClientSecret{}
|
|
err := crud.FromSecret(TypeLabelValue, secret, storedClientSecret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if storedClientSecret.Version != oidcClientSecretStorageVersion {
|
|
return nil, fmt.Errorf("%w: OIDC client secret storage has version %s instead of %s",
|
|
ErrOIDCClientSecretStorageVersion, storedClientSecret.Version, oidcClientSecretStorageVersion)
|
|
}
|
|
return storedClientSecret, nil
|
|
}
|