can now list notes

master
Jordan Orelli 10 years ago
parent 02ead712b2
commit c48700bf93

@ -87,6 +87,8 @@ func (c *Client) handleMessage(m Envelope) error {
return c.handleMeta(m.Body)
case "note":
return c.handleNote(m.Body)
case "list-notes":
return c.handleListNotes(m.Body)
default:
return fmt.Errorf("received message of unsupported type: %v", m.Kind)
}
@ -133,6 +135,38 @@ func (c *Client) handleNote(raw json.RawMessage) error {
return nil
}
func (c *Client) handleListNotes(raw json.RawMessage) error {
var notes ListNotesResponse
if err := json.Unmarshal(raw, &notes); err != nil {
return fmt.Errorf("unable to unmarshal listnotes response: %v", err)
}
writeNoteTitle := func(id int, title string) {
c.mu.Lock()
defer c.mu.Unlock()
c.trunc()
fmt.Printf("%d\t%s\n", id, title)
c.renderLine()
}
for _, note := range notes {
key, err := rsa.DecryptPKCS1v15(rand.Reader, c.key, note.Key)
if err != nil {
c.err("unable to decrypt note key: %v", err)
continue
}
title, err := c.aesDecrypt(key, note.Title)
if err != nil {
c.err("unable to decrype not title: %v", err)
continue
}
writeNoteTitle(note.Id, string(title))
}
return nil
}
func (c *Client) handshake() error {
r := &Auth{Nick: c.nick, Key: c.key.PublicKey}
c.info("authenticating as %s", c.nick)

@ -115,3 +115,9 @@ func getPublic() {
exit(1, "unable to marshal key: %v", err)
}
}
type KeyRequest string
func (k KeyRequest) Kind() string {
return "key"
}

@ -2,8 +2,19 @@ package main
import (
"crypto/rand"
"github.com/jordanorelli/lexnum"
)
var numEncoder = lexnum.NewEncoder('=', '-')
func encodeInt(n int) string {
return numEncoder.EncodeInt(n)
}
func decodeInt(s string) (int, error) {
return numEncoder.DecodeInt(s)
}
type GetNoteRequest int
func (g GetNoteRequest) Kind() string {
@ -42,5 +53,14 @@ func (l ListNotes) Kind() string {
return "list-notes"
}
type ListNotesResponse struct {
type ListNotesResponseItem struct {
Id int
Key []byte
Title []byte
}
type ListNotesResponse []ListNotesResponseItem
func (l ListNotesResponse) Kind() string {
return "list-notes"
}

@ -8,7 +8,6 @@ import (
"github.com/syndtr/goleveldb/leveldb/util"
"io"
"net"
"strconv"
"strings"
)
@ -55,6 +54,8 @@ func (s *serverConnection) handleRequest(request Envelope) error {
return s.handleNoteRequest(request.Body)
case "get-note":
return s.handleGetNoteRequest(request.Body)
case "list-notes":
return s.handleListNotesRequest(request.Body)
default:
return fmt.Errorf("no such request type: %v", request.Kind)
}
@ -117,13 +118,13 @@ func (s *serverConnection) handleNoteRequest(body json.RawMessage) error {
if it.Last() {
k := it.Key()
id_s := strings.TrimPrefix(string(k), "notes/")
lastId, err := strconv.Atoi(id_s)
lastId, err := decodeInt(id_s)
if err != nil {
return fmt.Errorf("error getting note id: %v", err)
}
id = lastId + 1
}
key := fmt.Sprintf("notes/%d", id)
key := fmt.Sprintf("notes/%s", encodeInt(id))
if err := s.db.Put([]byte(key), body, nil); err != nil {
return fmt.Errorf("unable to write note to db: %v", err)
}
@ -136,7 +137,7 @@ func (s *serverConnection) handleGetNoteRequest(body json.RawMessage) error {
if err := json.Unmarshal(body, &req); err != nil {
return fmt.Errorf("bad getnote request: %v", err)
}
key := fmt.Sprintf("notes/%d", req)
key := fmt.Sprintf("notes/%s", encodeInt(int(req)))
b, err := s.db.Get([]byte(key), nil)
if err != nil {
return fmt.Errorf("couldn't retrieve note: %v", err)
@ -151,6 +152,47 @@ func (s *serverConnection) handleGetNoteRequest(body json.RawMessage) error {
return nil
}
func (s *serverConnection) handleListNotesRequest(body json.RawMessage) error {
r := util.BytesPrefix([]byte("notes/"))
it := s.db.NewIterator(r, nil)
defer it.Release()
notes := make(ListNotesResponse, 0, 10)
it.Last()
for i := 0; it.Valid() && i < 10; i++ {
key, val := it.Key(), it.Value()
info_log.Printf("note %d has key %s", i, string(key))
id_s := strings.TrimPrefix(string(key), "notes/")
info_log.Printf("note id_s: %s", id_s)
id, err := decodeInt(id_s)
if err != nil {
error_log.Printf("unable to parse note key %s: %v", id_s, err)
it.Prev()
continue
}
info_log.Printf("note key: %s id: %d\n", key, id)
var note EncryptedNote
if err := json.Unmarshal(val, &note); err != nil {
error_log.Printf("unable to unmarshal encrypted note: %v", err)
it.Prev()
continue
}
notes = append(notes, ListNotesResponseItem{
Id: id,
Key: note.Key,
Title: note.Title,
})
it.Prev()
}
if err := it.Error(); err != nil {
return fmt.Errorf("error reading listnotes from db: %v", err)
}
return s.sendRequest(notes)
}
func (s *serverConnection) openDB() error {
path := fmt.Sprintf("./%s.db", s.nick)
db, err := leveldb.OpenFile(path, nil)

Loading…
Cancel
Save