proxy-pool/internal/gateway/transport/credentials.go

59 lines
1.9 KiB
Go

package transport
import (
"context"
"errors"
proxyDomain "github.com/proxy-pool/proxy-pool/internal/domain/proxy"
platformCredentials "github.com/proxy-pool/proxy-pool/internal/platform/credentials"
)
var (
ErrCredentialStoreRequired = errors.New("credential store is required")
ErrIncompleteCredentialReference = errors.New("proxy credential reference is incomplete")
ErrCredentialUsernameMismatch = errors.New("resolved credential username does not match proxy metadata")
)
// StoreCredentialResolver adapts the shared credential store to the data-plane
// transport without placing plaintext secrets in proxy snapshots.
type StoreCredentialResolver struct {
store platformCredentials.Store
}
var _ CredentialResolver = (*StoreCredentialResolver)(nil)
func NewStoreCredentialResolver(store platformCredentials.Store) (*StoreCredentialResolver, error) {
if store == nil {
return nil, ErrCredentialStoreRequired
}
return &StoreCredentialResolver{store: store}, nil
}
func (resolver *StoreCredentialResolver) Resolve(
ctx context.Context,
selected proxyDomain.Proxy,
) (Credentials, error) {
if selected.SecretRef == "" && selected.CredentialVersion == "" {
return Credentials{Username: selected.Username}, nil
}
if selected.SecretRef == "" || selected.CredentialVersion == "" {
return Credentials{}, ErrIncompleteCredentialReference
}
if resolver == nil || resolver.store == nil {
return Credentials{}, ErrCredentialStoreRequired
}
value, err := resolver.store.Resolve(ctx, platformCredentials.Reference{
SecretRef: selected.SecretRef,
CredentialVersion: selected.CredentialVersion,
})
if err != nil {
return Credentials{}, err
}
if value.Username == "" {
value.Username = selected.Username
} else if selected.Username != "" && value.Username != selected.Username {
return Credentials{}, ErrCredentialUsernameMismatch
}
return Credentials{Username: value.Username, Password: value.Password}, nil
}