jx/internal/config/openpgpkeyring.go
Matthew Rich 8e85305595
Some checks failed
Lint / golangci-lint (push) Failing after 10m2s
Declarative Tests / test (push) Failing after 21s
add openpgp keyring config
2025-08-25 04:00:49 +00:00

135 lines
3.0 KiB
Go

// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
package config
import (
"context"
"encoding/json"
"github.com/ProtonMail/go-crypto/openpgp"
"io"
"strings"
"strconv"
"gopkg.in/yaml.v3"
"decl/internal/data"
"decl/internal/codec"
"fmt"
"log/slog"
)
type OpenPGPKeyRing struct {
Keyring string `json:"keyring,omitempty" yaml:"keyring,omitempty"`
entities openpgp.EntityList
}
func NewOpenPGPKeyRing() *OpenPGPKeyRing {
o := &OpenPGPKeyRing{}
return o
}
func (o *OpenPGPKeyRing) URI() string {
return fmt.Sprintf("%s://%s", o.Type(), "")
}
func (o *OpenPGPKeyRing) SetURI(uri string) error {
return nil
}
func (o *OpenPGPKeyRing) SetParsedURI(uri data.URIParser) error {
return nil
}
func (o *OpenPGPKeyRing) Read(ctx context.Context) (yamlData []byte, err error) {
pemReader := io.NopCloser(strings.NewReader(o.Keyring))
o.entities, err = openpgp.ReadArmoredKeyRing(pemReader)
return
}
func (o *OpenPGPKeyRing) Load(r io.Reader) (err error) {
err = codec.NewYAMLDecoder(r).Decode(o)
if err == nil {
_, err = o.Read(context.Background())
}
return err
}
func (o *OpenPGPKeyRing) LoadYAML(yamlData string) (err error) {
err = codec.NewYAMLStringDecoder(yamlData).Decode(o)
slog.Info("OpenPGP.LoadYAML()", "keyring", len(o.Keyring), "err", err)
if err == nil {
_, err = o.Read(context.Background())
}
return err
}
func (o *OpenPGPKeyRing) UnmarshalJSON(data []byte) error {
if unmarshalErr := json.Unmarshal(data, o); unmarshalErr != nil {
return unmarshalErr
}
//o.NewReadConfigCommand()
return nil
}
func (o *OpenPGPKeyRing) UnmarshalYAML(value *yaml.Node) error {
type decodeOpenPGP OpenPGPKeyRing
if unmarshalErr := value.Decode((*decodeOpenPGP)(o)); unmarshalErr != nil {
return unmarshalErr
}
return nil
}
func (o *OpenPGPKeyRing) Clone() data.Configuration {
jsonGeneric, _ := json.Marshal(o)
clone := NewOpenPGPKeyRing()
if unmarshalErr := json.Unmarshal(jsonGeneric, &clone); unmarshalErr != nil {
panic(unmarshalErr)
}
return clone
}
func (o *OpenPGPKeyRing) Type() string {
return "openpgp"
}
func (o *OpenPGPKeyRing) GetEntityIndex(key string) (index int, field string, err error) {
values := strings.SplitN(key, ".", 2)
if len(values) == 2 {
if index, err = strconv.Atoi(values[0]); err == nil {
field = values[1]
}
} else {
err = data.ErrUnknownConfigurationKey
}
return
}
func (o *OpenPGPKeyRing) GetValue(name string) (result any, err error) {
index, field, err := o.GetEntityIndex(name)
if len(o.entities) > index && err == nil {
switch field {
case "PublicKey":
return o.entities[index].PrimaryKey, err
case "PrivateKey":
return o.entities[index].PrimaryKey, err
}
}
err = data.ErrUnknownConfigurationKey
return
}
// Expected key: 0.PrivateKey
func (o *OpenPGPKeyRing) Has(key string) (ok bool) {
index, field, err := o.GetEntityIndex(key)
if len(o.entities) > index && err == nil {
switch field {
case "PublicKey":
ok = o.entities[index].PrimaryKey != nil
case "PrivateKey":
ok = o.entities[index].PrimaryKey != nil
}
}
return
}