epoint-client += query documents by id
authornsz <nsz@port70.net>
Wed, 21 Dec 2011 02:46:27 +0000 (03:46 +0100)
committernsz <nsz@port70.net>
Wed, 21 Dec 2011 02:46:27 +0000 (03:46 +0100)
cmd/epoint-client/epoint-client.go

index 019a4d3..71bbe04 100644 (file)
@@ -21,12 +21,13 @@ import (
 
 var db *store.Conn
 
-const usage = `usage: ./epoint-client [k|d|s|v|c] [args..] < [seed|document]
+const usage = `usage: ./epoint-client [i|h|d|q|s|v|c] [args..] < [seed|document]
 server is http://localhost:8080 by default
 
 i - make issuer key, use seed for generation, args: denomination
 h - make holder key, use seed for generation, args: issuer
 d - make draft, use seed for signing key, args: targetid value
+q - query document, args: k|d|c id [server]
 s - submit a (key|draft|cert) document, args: k|d|c [server]
 v - verify a document (prints body of the document if ok)
 c - connect to server and get server key, args: [server]
@@ -172,6 +173,122 @@ func d(r []byte, target, value string) (err error) {
        return
 }
 
+func q(cmd, id, server string) (err error) {
+       log.Printf("document id: %s, server: %s", id, server)
+       m := map[string]string{
+               "k": "key",
+               "d": "draft",
+               "c": "cert",
+       }
+       k, ok := m[cmd]
+       if !ok {
+               err = fmt.Errorf("unknown query command: %s", cmd)
+               return
+       }
+       d, err := db.Get(k, id)
+       if err != nil {
+               if _, ok := err.(store.NotFoundError); !ok {
+                       return
+               }
+       } else {
+               _, err = os.Stdout.Write(d)
+               log.Printf("found %s in local store", id)
+               return
+       }
+       resp, err := http.Get(server+"/"+k+"/"+id)
+       if err != nil {
+               return
+       }
+       d, err = readall(resp.Body)
+       if err != nil {
+               return
+       }
+       err = resp.Body.Close()
+       if err != nil {
+               return
+       }
+       _, err = os.Stdout.Write(d)
+       if resp.StatusCode != 200 {
+               err = fmt.Errorf("request failed: %s", resp.Status)
+               return
+       }
+       if err != nil {
+               return
+       }
+       log.Printf("got %s from the server", id)
+       switch cmd {
+       case "k":
+               e, err1 := key.Parse(d)
+               err = err1
+               if err != nil {
+                       return
+               }
+               if id != key.Id(e) {
+                       err = fmt.Errorf("id mismatch, expected %s, got %s", id, key.Id(e))
+                       return
+               }
+               err = db.Set("key", id, d)
+       case "d":
+               i, s, err1 := document.Parse(d)
+               err = err1
+               if err != nil {
+                       return
+               }
+               if id != document.Id(s) {
+                       err = fmt.Errorf("id mismatch, expected %s, got %s", id, document.Id(s))
+                       return
+               }
+               draft := i.(*document.Draft)
+               b, err1 := db.Get("key", draft.Drawer)
+               err = err1
+               if err != nil {
+                       return
+               }
+               e, err1 := key.Parse(b)
+               err = err1
+               if err != nil {
+                       return
+               }
+               err = document.Verify(s, openpgp.EntityList{e})
+               if err != nil {
+                       return
+               }
+               err = db.Set("draft", id, d)
+       case "c":
+               i, s, err1 := document.Parse(d)
+               err = err1
+               if err != nil {
+                       return
+               }
+               if id != document.Id(s) {
+                       err = fmt.Errorf("id mismatch, expected %s, got %s", id, document.Id(s))
+                       return
+               }
+               cert, err1 := document.ToCert(i)
+               err = err1
+               if err != nil {
+                       return
+               }
+               // TODO: check serverkey
+               b, err1 := db.Get("key", cert.AuthorizedBy)
+               err = err1
+               if err != nil {
+                       return
+               }
+               e, err1 := key.Parse(b)
+               err = err1
+               if err != nil {
+                       return
+               }
+               err = document.Verify(s, openpgp.EntityList{e})
+               if err != nil {
+                       return
+               }
+               err = db.Set("cert", id, d)
+       }
+       return
+}
+
 func s(d []byte, cmd, server string) (err error) {
        m := map[string]string{
                "k": "key",
@@ -402,6 +519,20 @@ func main() {
                        log.Fatal(usage)
                }
                err = d(read(), os.Args[2], os.Args[3])
+       case "q":
+               cmd := ""
+               id := ""
+               if len(os.Args) == 5 {
+                       cmd = os.Args[2]
+                       id = os.Args[3]
+                       server = os.Args[4]
+               } else if len(os.Args) == 4 {
+                       cmd = os.Args[2]
+                       id = os.Args[3]
+               } else {
+                       log.Fatal(usage)
+               }
+               err = q(cmd, id, server)
        case "s":
                cmd := ""
                if len(os.Args) == 4 {