From 0213637dd662069e2d936e4274c5fda4b517dcda Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Thu, 27 Aug 2020 07:30:15 -0500 Subject: [PATCH] Persistence layer almost works. TODO: Fix test for `CreateKeypair` --- README.md | 3 +-- pigeon/db.go | 40 ++++++++++++++++++++++++++++++---------- pigeon/util.go | 21 ++++++--------------- pigeon/util_test.go | 18 ++++++++++++++++++ 4 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 pigeon/util_test.go diff --git a/README.md b/README.md index 8550afd..8fb45a3 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,9 @@ Don't use the Go version yet. If you want something stable, there is a [Ruby ver # TODO - - [ ] Finish http://go-database-sql.org/errors.html + - [ ] Finish http://go-database-sql.org/nulls.html - [ ] Add a real testing lib to DRY things up. - [ ] Get a good CI system going? Run tests at PR time, prevent coverage slips, etc.. - - [ ] Add a [database migration system](https://github.com/golang-migrate/migrate)? - [ ] Finish all the things below: |Done?|Verb |Noun | Flag / arg 1 | Flag 2 | diff --git a/pigeon/db.go b/pigeon/db.go index 95e4c5b..6d17c44 100644 --- a/pigeon/db.go +++ b/pigeon/db.go @@ -14,8 +14,11 @@ type migration struct { var migrations = []migration{ migration{ - up: `CREATE TABLE IF NOT EXISTS private_keys (id INTEGER PRIMARY KEY, secret TEXT NOT NULL);`, - down: `DROP TABLE IF EXISTS private_keys`, + up: `CREATE TABLE IF NOT EXISTS configs ( + id INTEGER PRIMARY KEY, + key TEXT NOT NULL + value TEXT NOT NULL);`, + down: `DROP TABLE IF EXISTS configs`, }, } @@ -52,16 +55,33 @@ func openDB() *sql.DB { // Database is a database object. Currently using modernc.org/ql var Database = openDB() -func tearDown() { +// SetConfig will write a key/value pair to the `configs` +// table +func SetConfig(key string, value []byte) { tx, err := Database.Begin() - if err != nil { - log.Fatalf("Failed to start transaction: %s", err) + log.Fatalf("Failed to SetConfig (1): %s", err) } - - for _, migration := range migrations { - tx.Exec(migration.down) + tx.Exec("INSERT INTO configs (?, ?)", key, value) + err1 := tx.Commit() + if err1 != nil { + log.Fatalf("Failed to SetConfig (2): %s", err) } - - tx.Commit() +} + +// GetConfig retrieves a key/value pair from the database. +func GetConfig(key string) []byte { + rows, err := Database.Query("SELECT key FROM configs WHERE value = ? LIMIT 1", key) + if err != nil { + log.Fatalf("Unable to retrieve config key(1): %s", err) + } + var result []byte + for rows.Next() { + err := rows.Scan(&result) + if err != nil { + log.Fatalf("Unable to retrieve config key(2): %s", err) + } + } + + return result } diff --git a/pigeon/util.go b/pigeon/util.go index 02119ad..2f64b09 100644 --- a/pigeon/util.go +++ b/pigeon/util.go @@ -4,27 +4,18 @@ import ( "crypto/ed25519" "fmt" "log" - "os" ) -// CreateKeypair makes a new ED25519 key pair. Just a thin -// wrapper around crypto/ed25519. -func createKeypair() (ed25519.PublicKey, ed25519.PrivateKey) { - pub, priv, err := ed25519.GenerateKey(nil) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - return pub, priv -} - // CreateIdentity is used by the CLI to create an ED25519 // keypair and store it to disk. It returns the private key // as a Base32 encoded string func CreateIdentity() (ed25519.PublicKey, ed25519.PrivateKey) { - pub, priv := createKeypair() - fmt.Println("Add persistence here") + pub, priv, err := ed25519.GenerateKey(nil) + if err != nil { + log.Fatalf("Keypair creation error %s", err) + } + SetConfig("pubic_key", pub) + SetConfig("private_key", priv) return pub, priv } diff --git a/pigeon/util_test.go b/pigeon/util_test.go new file mode 100644 index 0000000..00f36ee --- /dev/null +++ b/pigeon/util_test.go @@ -0,0 +1,18 @@ +package pigeon + +import ( + "bytes" + "testing" +) + +func TestCreateIdentity(t *testing.T) { + pub, priv := CreateIdentity() + + if !bytes.Equal(pub, GetConfig("public_key")) { + t.Fail() + } + + if !bytes.Equal(priv, GetConfig("private_key")) { + t.Fail() + } +}