2 Commits
Author SHA1 Message Date
dm efbe79e786 tests: added NewKeyPair and ListKeys
Signed-off-by: Derek McQuay <derekmcquay@gmail.com>
2018-02-27 20:10:59 -08:00
dm c4d67105f2 add checkDir for keyring
ensureDir will create the dir, which for calls like List, Sign, Remove,
etc. should not occur. It should only perform the actions if something
exists there

Signed-off-by: Derek McQuay <derekmcquay@gmail.com>
2018-02-27 19:39:14 -08:00
4 changed files with 110 additions and 72 deletions
-29
View File
@@ -6,7 +6,6 @@ import (
"os" "os"
"mcquay.me/pm/keyring" "mcquay.me/pm/keyring"
"mcquay.me/pm/pkg"
) )
const usage = `pm: simple, cross-platform system package manager const usage = `pm: simple, cross-platform system package manager
@@ -14,7 +13,6 @@ const usage = `pm: simple, cross-platform system package manager
subcommands: subcommands:
environ (env) -- print environment information environ (env) -- print environment information
keyring (key) -- interact with pm's OpenPGP keyring keyring (key) -- interact with pm's OpenPGP keyring
package (pkg) -- create packages
` `
const keyUsage = `pm keyring: interact with pm's OpenPGP keyring const keyUsage = `pm keyring: interact with pm's OpenPGP keyring
@@ -29,12 +27,6 @@ subcommands:
verify (v) -- verify a detached signature verify (v) -- verify a detached signature
` `
const pkgUsage = `pm package: generate pm-compatible packages
subcommands:
create (c) -- create a fresh keypair
`
func main() { func main() {
if len(os.Args) < 2 { if len(os.Args) < 2 {
fatalf("pm: missing subcommand\n\n%v", usage) fatalf("pm: missing subcommand\n\n%v", usage)
@@ -134,27 +126,6 @@ func main() {
default: default:
fatalf("unknown keyring subcommand: %q\n\nusage: %v", sub, keyUsage) fatalf("unknown keyring subcommand: %q\n\nusage: %v", sub, keyUsage)
} }
case "package", "pkg":
if len(os.Args[1:]) < 2 {
fatalf("pm package: insufficient args\n\nusage: %v", pkgUsage)
}
sub := os.Args[2]
switch sub {
case "create", "creat", "c":
if signID == "" {
fatalf("must set PM_PGP_ID\n")
}
args := os.Args[3:]
if len(args) != 1 {
fatalf("usage: pm package create <directory>\n")
}
dir := args[0]
if err := pkg.Create(root, signID, dir); err != nil {
fatalf("creating package: %v\n", err)
}
default:
fatalf("unknown package subcommand: %q\n\nusage: %v", sub, pkgUsage)
}
default: default:
fatalf("uknown subcommand %q\n\nusage: %v", cmd, usage) fatalf("uknown subcommand %q\n\nusage: %v", cmd, usage)
} }
+20 -17
View File
@@ -78,8 +78,8 @@ func NewKeyPair(root, name, email string) error {
// ListKeys prints keyring information to w. // ListKeys prints keyring information to w.
func ListKeys(root string, w io.Writer) error { func ListKeys(root string, w io.Writer) error {
if err := ensureDir(root); err != nil { if err := checkDir(root); err != nil {
return errors.Wrap(err, "can't find or create pgp dir") return errors.Wrap(err, "can't find pgp dir")
} }
srn, prn := getNames(root) srn, prn := getNames(root)
secs, pubs, err := getELs(srn, prn) secs, pubs, err := getELs(srn, prn)
@@ -105,8 +105,8 @@ func ListKeys(root string, w io.Writer) error {
// Export prints pubkey information associated with email to w. // Export prints pubkey information associated with email to w.
func Export(root string, w io.Writer, email string) error { func Export(root string, w io.Writer, email string) error {
if err := ensureDir(root); err != nil { if err := checkDir(root); err != nil {
return errors.Wrap(err, "can't find or create pgp dir") return errors.Wrap(err, "can't find pgp dir")
} }
srn, prn := getNames(root) srn, prn := getNames(root)
_, pubs, err := getELs(srn, prn) _, pubs, err := getELs(srn, prn)
@@ -142,8 +142,8 @@ func Import(root string, w io.Reader) error {
return errors.Wrap(err, "reading keyring") return errors.Wrap(err, "reading keyring")
} }
if err := ensureDir(root); err != nil { if err := checkDir(root); err != nil {
return errors.Wrap(err, "can't find or create pgp dir") return errors.Wrap(err, "can't find pgp dir")
} }
srn, prn := getNames(root) srn, prn := getNames(root)
_, pubs, err := getELs(srn, prn) _, pubs, err := getELs(srn, prn)
@@ -185,8 +185,8 @@ func Import(root string, w io.Reader) error {
// Sign takes an id and a reader and writes the signature for that id to sig. // Sign takes an id and a reader and writes the signature for that id to sig.
func Sign(root, id string, in io.Reader, sig io.Writer) error { func Sign(root, id string, in io.Reader, sig io.Writer) error {
if err := ensureDir(root); err != nil { if err := checkDir(root); err != nil {
return errors.Wrap(err, "can't find or create pgp dir") return errors.Wrap(err, "can't find pgp dir")
} }
srn, prn := getNames(root) srn, prn := getNames(root)
secs, _, err := getELs(srn, prn) secs, _, err := getELs(srn, prn)
@@ -206,8 +206,8 @@ func Sign(root, id string, in io.Reader, sig io.Writer) error {
// Verify verifies a file's deatched signature. // Verify verifies a file's deatched signature.
func Verify(root string, file, sig io.Reader) error { func Verify(root string, file, sig io.Reader) error {
if err := ensureDir(root); err != nil { if err := checkDir(root); err != nil {
return errors.Wrap(err, "can't find or create pgp dir") return errors.Wrap(err, "can't find pgp dir")
} }
srn, prn := getNames(root) srn, prn := getNames(root)
_, pubs, err := getELs(srn, prn) _, pubs, err := getELs(srn, prn)
@@ -225,8 +225,8 @@ func Verify(root string, file, sig io.Reader) error {
// It skips public keys that have matching secret keys, and does not effect // It skips public keys that have matching secret keys, and does not effect
// private keys. // private keys.
func Remove(root string, id string) error { func Remove(root string, id string) error {
if err := ensureDir(root); err != nil { if err := checkDir(root); err != nil {
return errors.Wrap(err, "can't find or create pgp dir") return errors.Wrap(err, "can't find pgp dir")
} }
srn, prn := getNames(root) srn, prn := getNames(root)
secs, pubs, err := getELs(srn, prn) secs, pubs, err := getELs(srn, prn)
@@ -266,6 +266,14 @@ func pGPDir(root string) string {
return filepath.Join(root, "var", "lib", "pm", "pgp") return filepath.Join(root, "var", "lib", "pm", "pgp")
} }
func checkDir(root string) error {
d := pGPDir(root)
if !fs.Exists(d) {
return fmt.Errorf("pgp dir does not exist")
}
return nil
}
func ensureDir(root string) error { func ensureDir(root string) error {
d := pGPDir(root) d := pGPDir(root)
if !fs.Exists(d) { if !fs.Exists(d) {
@@ -340,8 +348,3 @@ func findKey(el openpgp.EntityList, id string) (*openpgp.Entity, error) {
} }
return e, fmt.Errorf("key %q not found", id) return e, fmt.Errorf("key %q not found", id)
} }
// FindSecretEntity searches for id in the secret keyring.
func FindSecretEntity(root, id string) (*openpgp.Entity, error) {
return nil, errors.New("NYI")
}
+90
View File
@@ -0,0 +1,90 @@
package keyring
import (
"bytes"
"io/ioutil"
"os"
"regexp"
"testing"
)
const (
ExpectedListKeysRegex = "sec: [[:alnum:]]{8}:[[:space:]]*foo[[:space:]]*\\(pm\\)[[:space:]]*<bar>\npub: [[:alnum:]]{8}:[[:space:]]*foo[[:space:]]*\\(pm\\)[[:space:]]*<bar>"
)
func TestNewKeyPair(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("Couldn't create tmpdir")
}
defer os.RemoveAll(tmpdir)
var newKeyPair = []struct {
r, n, e string
expected bool
}{
{"", "", "", false},
{"", "foo", "", false},
{"", "foo", "bad<>email", false},
{tmpdir, "foo", "bar", true},
}
for _, rt := range newKeyPair {
actual := NewKeyPair(rt.r, rt.n, rt.e)
if (actual == nil) != rt.expected {
t.Errorf(
"failed NewKeyPair with an error: %v\n\troot: %s\n\tname: %s\n\temail:%s\n\texpected: %t\n\t actual: %t",
actual,
rt.r,
rt.n,
rt.e,
(actual == nil),
rt.expected,
)
}
}
}
func TestListKeys(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("Couldn't create tmpdir")
}
defer os.RemoveAll(tmpdir)
err = NewKeyPair(tmpdir, "foo", "bar")
if err != nil {
t.Fatalf("Couldn't create New Key Pair")
}
var newKeyPair = []struct {
r string
regex string
w *bytes.Buffer
expected bool
}{
{"", "", bytes.NewBuffer(nil), false},
{tmpdir, ExpectedListKeysRegex, bytes.NewBuffer(nil), true},
}
for _, rt := range newKeyPair {
actual := ListKeys(rt.r, rt.w)
if (actual == nil) != rt.expected {
t.Errorf(
"failed ListKeys with an error: %v\n\troot: %s\n\texpected: %t\n\t actual: %t",
actual,
rt.r,
(actual == nil),
rt.expected,
)
}
if rt.expected {
matched, err := regexp.MatchString(rt.regex, rt.w.String())
if err != nil {
t.Fatalf("error%v, ", err)
}
if !matched {
t.Errorf("did not match")
t.Errorf("ListKeys did not match expected regex; wanted: [%q], got: [%s]", rt.regex, rt.w.String())
}
}
}
}
-26
View File
@@ -1,26 +0,0 @@
package pkg
import (
"fmt"
"log"
"github.com/pkg/errors"
"mcquay.me/fs"
"mcquay.me/pm/keyring"
)
// Create traverses the contents of dir and emits a valid pkg, signed by id
func Create(root, id, dir string) error {
if !fs.Exists(dir) {
return fmt.Errorf("%q: doesn't exist", dir)
}
if !fs.IsDir(dir) {
return fmt.Errorf("%q: is not a directory", dir)
}
e, err := keyring.FindSecretEntity(dir, id)
if err != nil {
return errors.Wrap(err, "find secret key")
}
log.Printf("found key: %v", e.PrimaryKey.KeyIdShortString())
return fmt.Errorf("creating package from %q for %q: NYI", dir, id)
}