Add example and small CLI
Signed-off-by: jolheiser <john.olheiser@gmail.com>main v0.0.2
parent
fcfe79244f
commit
eb0d378523
|
@ -0,0 +1,23 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"go.jolheiser.com/confage"
|
||||
|
||||
|
||||
)
|
||||
|
||||
func main() {
|
||||
fs := flag.NewFlagSet("confage", flag.ExitOnError)
|
||||
secretKeyFlag := fs.String("secret-key", "", "Age secret key")
|
||||
fs.StringVar(secretKeyFlag, "s", *secretKeyFlag, "--secret-key")
|
||||
if err := fs.Parse(os.Args[1:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t := confage.MustNew(*secretKeyFlag, fs.Arg(0))
|
||||
fmt.Println(t.String())
|
||||
}
|
22
confage.go
22
confage.go
|
@ -38,8 +38,7 @@ func New[T any](key string, val T) (v Type[T], err error) {
|
|||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
i = ii
|
||||
r = ii.Recipient()
|
||||
i, r = ii, ii.Recipient()
|
||||
default:
|
||||
i, err = age.NewScryptIdentity(key)
|
||||
if err != nil {
|
||||
|
@ -65,40 +64,47 @@ func (t Type[T]) String() string {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.MarshalText
|
||||
func (v Type[T]) MarshalText() ([]byte, error) {
|
||||
func (t Type[T]) MarshalText() ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
w, err := age.Encrypt(&b, v.r)
|
||||
w, err := age.Encrypt(&b, t.r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.NewEncoder(w).Encode(v.Value); err != nil {
|
||||
|
||||
if err := json.NewEncoder(w).Encode(t.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := w.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := base64.StdEncoding.EncodeToString(b.Bytes())
|
||||
return []byte(out), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.UnmarshalText
|
||||
func (v *Type[T]) UnmarshalText(text []byte) error {
|
||||
func (t *Type[T]) UnmarshalText(text []byte) error {
|
||||
b, err := base64.StdEncoding.DecodeString(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r, err := age.Decrypt(bytes.NewBuffer(b), v.i)
|
||||
|
||||
r, err := age.Decrypt(bytes.NewBuffer(b), t.i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
if _, err := io.Copy(&out, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var val T
|
||||
if err := json.Unmarshal(out.Bytes(), &val); err != nil {
|
||||
return err
|
||||
}
|
||||
(*v).Value = val
|
||||
|
||||
(*t).Value = val
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package confage_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"go.jolheiser.com/confage"
|
||||
|
||||
|
||||
)
|
||||
|
||||
func Example_config() {
|
||||
const secretKey = "AGE-SECRET-KEY-1AN83H8JECDKHSD2RN70WU8RQYYH3C309UUYQQ0EPQNJR3ZXRDHESTUCCM4" // age1ynmpzgvrqj3r6z39kp3p852afe3nkc3neem80vgq96jt2zhesezq8yhn02
|
||||
|
||||
cfg := &Config{
|
||||
Password: confage.MustNew(secretKey, ""),
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(config, &cfg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(cfg.Password.Value)
|
||||
// Output:
|
||||
// bar
|
||||
}
|
||||
|
||||
// Example config struct
|
||||
type Config struct {
|
||||
Username string
|
||||
Password confage.Type[string]
|
||||
}
|
||||
|
||||
// config.json living on disk
|
||||
var config = []byte(`{
|
||||
"username": "foo",
|
||||
"password": "YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0b3pzdTVtcnBBUFV3bnNsa2RIYlhTVGVYeXlHcHpIbEpMR3ZwcWxHMmtjClc5ald4MHZhdFFKY3NmS0R5bFpXY1VGa1RKeWxHaGVzR3FhS1B1NHgydUkKLS0tIEJYRnhMNm12aE14bUU5bGNPVFBJcHBWZDJBeWFMMVdMUGdyVXErOVFuaWsK3F0DfPH+Ud50XIBoDR2D/+/PMoqNp9O2R6BdBLTLyiENJYrxGxo="
|
||||
}`)
|
|
@ -7,29 +7,82 @@ import (
|
|||
"github.com/matryer/is"
|
||||
)
|
||||
|
||||
func TestTypeScrypt(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
const (
|
||||
passphrase = "passphrase"
|
||||
secretKey = "AGE-SECRET-KEY-1F7SU7MXLVHU0SWQ3L2ZMW7G2NN2YTH88NLU6LVDHENTZLMCT3M5S799RDK"
|
||||
)
|
||||
|
||||
enc := MustNew("passphrase", 0)
|
||||
enc.Value = 100
|
||||
type Struct struct {
|
||||
String string
|
||||
Int int
|
||||
Bool bool
|
||||
}
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
t.Run("string", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
val := "foo"
|
||||
testEncryption(assert, passphrase, val)
|
||||
testEncryption(assert, secretKey, val)
|
||||
})
|
||||
|
||||
t.Run("int", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
val := 123
|
||||
testEncryption(assert, passphrase, val)
|
||||
testEncryption(assert, secretKey, val)
|
||||
})
|
||||
|
||||
t.Run("bool", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
val := true
|
||||
testEncryption(assert, passphrase, val)
|
||||
testEncryption(assert, secretKey, val)
|
||||
})
|
||||
|
||||
t.Run("map", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
val := map[string]any{
|
||||
"foo": "bar",
|
||||
"baz": 123.0,
|
||||
"bux": false,
|
||||
}
|
||||
testEncryption(assert, passphrase, val)
|
||||
testEncryption(assert, secretKey, val)
|
||||
})
|
||||
|
||||
t.Run("struct", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
val := Struct{
|
||||
String: "string",
|
||||
Int: 123,
|
||||
Bool: true,
|
||||
}
|
||||
testEncryption(assert, passphrase, val)
|
||||
testEncryption(assert, secretKey, val)
|
||||
})
|
||||
|
||||
t.Run("pointer", func(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
val := &Struct{
|
||||
String: "string",
|
||||
Int: 123,
|
||||
Bool: true,
|
||||
}
|
||||
testEncryption(assert, passphrase, val)
|
||||
testEncryption(assert, secretKey, val)
|
||||
})
|
||||
}
|
||||
|
||||
func testEncryption[T any](assert *is.I, key string, value T) {
|
||||
assert.Helper()
|
||||
|
||||
enc := MustNew(key, value)
|
||||
payload, err := json.Marshal(enc)
|
||||
assert.NoErr(err) // Should be able to marshal JSON
|
||||
|
||||
dec := MustNew("passphrase", 0)
|
||||
err = json.Unmarshal(payload, &dec)
|
||||
assert.NoErr(err) // Should be able to unmarshal JSON
|
||||
|
||||
assert.Equal(enc.Value, dec.Value) // Values should match
|
||||
}
|
||||
|
||||
func TestTypeX25519(t *testing.T) {
|
||||
assert := is.New(t)
|
||||
|
||||
enc := MustNew("AGE-SECRET-KEY-1F7SU7MXLVHU0SWQ3L2ZMW7G2NN2YTH88NLU6LVDHENTZLMCT3M5S799RDK", 100)
|
||||
payload, err := json.Marshal(enc)
|
||||
assert.NoErr(err) // Should be able to marshal JSON
|
||||
|
||||
dec := MustNew("AGE-SECRET-KEY-1F7SU7MXLVHU0SWQ3L2ZMW7G2NN2YTH88NLU6LVDHENTZLMCT3M5S799RDK", 0)
|
||||
var t T
|
||||
dec := MustNew(key, t)
|
||||
err = json.Unmarshal(payload, &dec)
|
||||
assert.NoErr(err) // Should be able to unmarshal JSON
|
||||
|
||||
|
|
Loading…
Reference in New Issue