Gitignore updates
This commit is contained in:
parent
333007ec72
commit
e1f120cc3f
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,6 +2,7 @@ pigeon-cli
|
|||
*nutsdb*
|
||||
*scratchpad*
|
||||
*.dat
|
||||
pigeon/pigeon_metadata/*
|
||||
pigeon/testdata/*
|
||||
testdata/*
|
||||
*.out
|
||||
*.db
|
||||
|
|
3
go.sum
3
go.sum
|
@ -37,6 +37,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
|||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
|
@ -149,6 +150,7 @@ github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bA
|
|||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
|
@ -204,6 +206,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
||||
var encoder = base32.NewEncoding(alphabet).WithPadding(base32.NoPadding)
|
||||
|
||||
// B32Encode does Crockford 32 encoding on a string.
|
||||
func B32Encode(data []byte) string {
|
||||
return encoder.EncodeToString(data)
|
||||
}
|
||||
|
||||
// B32Decode takes a Crockford Base32 string and converts it
|
||||
// to a byte array.
|
||||
func B32Decode(input string) []byte {
|
||||
output, error := encoder.DecodeString(input)
|
||||
if error != nil {
|
||||
msg := fmt.Sprintf("Error decoding Base32 string %s", input)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
decoded []byte
|
||||
encoded string
|
||||
}
|
||||
|
||||
var tests = []testCase{
|
||||
testCase{
|
||||
decoded: []byte{59, 73, 66, 126, 252, 150, 123, 166, 113, 107, 198, 52, 255, 236, 72, 112, 9, 146, 232, 12, 69, 165, 210, 202, 156, 63, 51, 62, 106, 207, 182, 107},
|
||||
encoded: "7D4M4ZQWJSXTCWBBRRTFZV28E04S5T0C8PJX5JMW7WSKWTPFPSNG",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{143, 151, 30, 105, 79, 74, 193, 242, 224, 97, 106, 227, 223, 99, 236, 225, 145, 236, 152, 143, 230, 159, 247, 50, 72, 147, 217, 248, 255, 67, 126, 116},
|
||||
encoded: "HYBHWTAF9B0Z5R31DBHXYRZCW68YS64FWTFZECJ8JFCZHZT3FST0",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{100, 138, 58, 29, 215, 203, 249, 249, 62, 224, 216, 70, 191, 13, 224, 150, 174, 81, 39, 125, 64, 93, 9, 192, 175, 93, 64, 75, 181, 93, 81, 22},
|
||||
encoded: "CJ53M7EQSFWZJFQ0V13BY3F0JTQ529VX81EGKG5FBN04QDAXA4B0",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{145, 30, 158, 33, 248, 234, 78, 70, 108, 212, 167, 42, 151, 249, 37, 177, 36, 250, 110, 73, 89, 241, 190, 70, 7, 142, 119, 158, 15, 232, 228, 115},
|
||||
encoded: "J4F9W8FRX974CV6MMWN9FY95P4JFMVJ9B7RVWHG7HSVSW3Z8WHSG",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{37, 190, 191, 20, 201, 161, 145, 108, 193, 112, 198, 34, 70, 92, 202, 167, 162, 124, 60, 25, 10, 67, 41, 140, 96, 103, 124, 71, 72, 191, 144, 0},
|
||||
encoded: "4PZBY569M68PSGBGRRH4CQ6AMYH7RF0S191JK330CXY4EJ5ZJ000",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{233, 132, 69, 72, 63, 230, 64, 151, 188, 152, 73, 210, 186, 131, 153, 16, 14, 45, 110, 197, 208, 121, 102, 71, 232, 141, 240, 85, 238, 138, 91, 47},
|
||||
encoded: "X624AJ1ZWS09FF4R979BN0WS2072TVP5T1WPCHZ8HQR5BVMABCQG",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{70, 145, 156, 235, 127, 126, 254, 123, 13, 86, 173, 10, 182, 10, 39, 151, 200, 255, 56, 48, 38, 61, 155, 72, 1, 117, 232, 111, 145, 93, 184, 104},
|
||||
encoded: "8T8SSTVZFVZ7P3APNM5BC2H7JZ4FYE1G4RYSPJ01EQM6Z4AXQ1M0",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{40, 63, 195, 179, 116, 218, 206, 16, 126, 171, 14, 202, 210, 155, 187, 6, 117, 172, 181, 137, 46, 251, 109, 24, 107, 252, 33, 95, 206, 56, 31, 26},
|
||||
encoded: "50ZW7CVMVB710ZNB1V5D56XV0STTSDC95VXPT63BZGGNZKHR3WD0",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{16, 249, 237, 62, 116, 10, 80, 20, 123, 50, 75, 103, 228, 127, 214, 26, 199, 49, 83, 34, 66, 24, 242, 155, 240, 60, 18, 25, 205, 187, 156, 76},
|
||||
encoded: "23WYTFKM19818YSJ9DKY8ZYP3B3K2MS288CF56ZG7G91KKDVKH60",
|
||||
},
|
||||
testCase{
|
||||
decoded: []byte{233, 110, 203, 25, 190, 221, 178, 24, 29, 138, 26, 65, 46, 246, 187, 122, 92, 164, 70, 199, 71, 11, 113, 163, 218, 251, 157, 151, 127, 152, 213, 192},
|
||||
encoded: "X5QCP6DYVPS1G7CA390JXXNVF9EA8HP78W5Q38YTZEESEZWRTQ00",
|
||||
},
|
||||
}
|
||||
|
||||
func TestB32Encode(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
actual := B32Encode(test.decoded)
|
||||
expected := test.encoded
|
||||
if actual != expected {
|
||||
fmt.Printf("FAIL:\n Exp: %s\n Act: %s\n", expected, actual)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestB32Decode(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
actual := B32Decode(test.encoded)
|
||||
expected := test.decoded
|
||||
if len(actual) != len(expected) {
|
||||
fmt.Printf("\nFAIL: length mismatch at tests[%d]", i)
|
||||
t.Fail()
|
||||
}
|
||||
for j, x := range expected {
|
||||
if actual[j] != x {
|
||||
msg := "tests[%d].encoded[%d] did not decode B32 properly (%s)"
|
||||
fmt.Printf(msg, j, i, test.encoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defer func() { recover() }()
|
||||
B32Decode("U")
|
||||
t.Errorf("Expected Base32 decode panic. It Did not panic.")
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
// Version is the current version of Pigeon CLI
|
||||
const Version = "0.0.0"
|
||||
|
||||
// BlobSigil is a string identifier that precedes a base32
|
||||
// hash (SHA256) representing arbitrary data.
|
||||
const BlobSigil = "FILE."
|
||||
|
||||
// MessageSigil is a string identifier that precedes a base32
|
||||
// hash (SHA256) representing arbitrary data.
|
||||
const MessageSigil = "TEXT."
|
||||
|
||||
// UserSigil is a string identifier that precedes a base32
|
||||
// representation of a particular user's ED25519 public key.
|
||||
const UserSigil = "USER."
|
||||
|
||||
// StringSigil is a character used to identify strings as
|
||||
// defined by the pigeon protocol spec.
|
||||
const StringSigil = "\""
|
||||
|
||||
// DefaultDBPath describes the default storage location for
|
||||
// the database instance.
|
||||
const DefaultDBPath = "./pigeondb"
|
|
@ -1,30 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var createCmd = &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create various resources (identity, drafts, blob)",
|
||||
Aliases: []string{"make", "new"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
},
|
||||
}
|
||||
|
||||
var identityCmd = &cobra.Command{
|
||||
Use: "identity",
|
||||
Short: "Create a new pigeon identity",
|
||||
Aliases: []string{"id"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
pub, _ := CreateIdentity()
|
||||
fmt.Println(B32Encode(pub))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(createCmd)
|
||||
createCmd.AddCommand(identityCmd)
|
||||
}
|
95
pigeon/db.go
95
pigeon/db.go
|
@ -1,95 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
"modernc.org/ql"
|
||||
)
|
||||
|
||||
type migration struct {
|
||||
up string
|
||||
down string
|
||||
}
|
||||
|
||||
var migrations = []migration{
|
||||
migration{
|
||||
up: `CREATE TABLE IF NOT EXISTS configs (
|
||||
key string NOT NULL,
|
||||
value string NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS unique_configs_key ON configs (key);
|
||||
`,
|
||||
down: `DROP TABLE IF EXISTS configs`,
|
||||
},
|
||||
}
|
||||
|
||||
func openDB() *sql.DB {
|
||||
ql.RegisterDriver()
|
||||
|
||||
db, err0 := sql.Open("ql", "file://pigeon_metadata/secret.db")
|
||||
|
||||
if err0 != nil {
|
||||
log.Fatalf("failed to open db: %s", err0)
|
||||
}
|
||||
|
||||
err1 := db.Ping()
|
||||
|
||||
if err1 != nil {
|
||||
log.Fatalf("failed to ping db: %s", err1)
|
||||
}
|
||||
|
||||
tx, err := db.Begin()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to start transaction: %s", err)
|
||||
}
|
||||
|
||||
for _, migration := range migrations {
|
||||
_, err := tx.Exec(migration.up)
|
||||
if err != nil {
|
||||
log.Fatalf("Migration failure: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if tx.Commit() != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
// Database is a database object. Currently using modernc.org/ql
|
||||
var Database = openDB()
|
||||
|
||||
// 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 SetConfig (0): %s", err)
|
||||
}
|
||||
_, err2 := tx.Exec("INSERT INTO configs(key, value) VALUES(?1, ?2)", key, string(value))
|
||||
if err2 != nil {
|
||||
log.Fatalf("Failed to SetConfig (1): %s", err2)
|
||||
}
|
||||
err1 := tx.Commit()
|
||||
if err1 != nil {
|
||||
log.Fatalf("Failed to SetConfig (2): %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig retrieves a key/value pair from the database.
|
||||
func GetConfig(key string) []byte {
|
||||
var result string
|
||||
row := Database.QueryRow("SELECT value FROM configs WHERE key=$1", key)
|
||||
err := row.Scan(&result)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
log.Fatalf("CONFIG MISSING: %s", key)
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return []byte(result)
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func resetDB() {
|
||||
tx, err := Database.Begin()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to start transaction: %s", err)
|
||||
}
|
||||
|
||||
for i := len(migrations) - 1; i >= 0; i-- {
|
||||
_, err := tx.Exec(migrations[i].down)
|
||||
if err != nil {
|
||||
log.Fatalf("Migration failure: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, migration := range migrations {
|
||||
_, err := tx.Exec(migration.up)
|
||||
if err != nil {
|
||||
log.Fatalf("Migration failure: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if tx.Commit() != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetUpTeardown(t *testing.T) {
|
||||
resetDB()
|
||||
db := Database
|
||||
err := db.Ping()
|
||||
if err != nil {
|
||||
t.Fatalf("Test setup failed: %s", err)
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "pigeon-cli",
|
||||
Short: "An off-grid, serverless, peer-to-peer protocol for building software that works on poor internet connections, or entirely offline.",
|
||||
Long: `Pigeon enables offline and off-grid computer systems to exchange messages
|
||||
in a way that is delay tolerant, tamper resistant and easily transmitted
|
||||
over non-networked systems (such as sneakernet).`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("Hello, Cobra!")
|
||||
},
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
func Execute() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.pigeon.yaml)")
|
||||
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
|
||||
// initConfig reads in config file and ENV variables if set.
|
||||
func initConfig() {
|
||||
if cfgFile != "" {
|
||||
// Use config file from the flag.
|
||||
viper.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
// Find home directory.
|
||||
home, err := homedir.Dir()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Search config in home directory with name ".pigeon" (without extension).
|
||||
viper.AddConfigPath(home)
|
||||
viper.SetConfigName(".pigeon")
|
||||
}
|
||||
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
// If a config file is found, read it in.
|
||||
if err := viper.ReadInConfig(); err == nil {
|
||||
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"log"
|
||||
)
|
||||
|
||||
// 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, err := ed25519.GenerateKey(nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Keypair creation error %s", err)
|
||||
}
|
||||
SetConfig("public_key", pub)
|
||||
SetConfig("private_key", priv)
|
||||
return pub, priv
|
||||
}
|
||||
|
||||
// EncodeUserMhash Takes a []byte and converts it to a B32
|
||||
// string in the format "USER.DATA.ED25519"
|
||||
// func EncodeUserMhash(pubKey []byte) string {
|
||||
// b32 := B32Encode(pubKey)
|
||||
// b32Length := len(b32)
|
||||
|
||||
// if b32Length != 52 {
|
||||
// m := "Expected %s to be 52 bytes long. Got %d"
|
||||
// log.Fatal(m, b32, b32Length)
|
||||
// }
|
||||
|
||||
// return fmt.Sprintf("%s%s", UserSigil, b32)
|
||||
// }
|
|
@ -1,21 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCreateIdentity(t *testing.T) {
|
||||
resetDB()
|
||||
pub, priv := CreateIdentity()
|
||||
dbPubKey := GetConfig("public_key")
|
||||
dbPrivKey := GetConfig("private_key")
|
||||
|
||||
if !bytes.Equal(pub, dbPubKey) {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if !bytes.Equal(priv, dbPrivKey) {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package pigeon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Show the version of the Pigeon CLI tool.",
|
||||
Long: ``,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
result := fmt.Sprintf("Pigeon v%s", Version)
|
||||
fmt.Println(result)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
}
|
Loading…
Reference in New Issue
Block a user