From fe8addb0ae9a443837db53213bf513660618bdac Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sun, 28 Dec 2014 15:48:56 -0500 Subject: [PATCH] users can send and receive messages --- client.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ message.go | 42 +++++++++++++++++++++++++++++++++++++ server.go | 21 +++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 message.go diff --git a/client.go b/client.go index b32e278..701cc45 100644 --- a/client.go +++ b/client.go @@ -287,6 +287,8 @@ func (c *Client) exec(line string) { c.sendMessage(parts[1:]) case "msg/list": c.listMessages(parts[1:]) + case "msg/get": + c.getMessage(parts[1:]) default: c.err("unrecognized client command: %s", parts[0]) } @@ -535,6 +537,65 @@ func (c *Client) listMessages(args []string) { } } +func (c *Client) getMessage(args []string) { + if len(args) != 1 { + c.err("msg/get requires exactly 1 argument: the id of the message to get") + return + } + + id, err := strconv.Atoi(args[0]) + if err != nil { + c.err("%v", err) + return + } + + promise, err := c.sendRequest(GetMessage{Id: id}) + if err != nil { + c.err("%v", err) + return + } + + raw := <-promise + + var msg Message + if err := json.Unmarshal(raw.Body, &msg); err != nil { + c.err("%v", err) + return + } + + key, err := c.rsaDecrypt(msg.Key) + if err != nil { + c.err("%v", err) + return + } + + from, err := c.aesDecrypt(key, msg.From) + if err != nil { + c.err("%v", err) + return + } + + text, err := c.aesDecrypt(key, msg.Text) + if err != nil { + c.err("%v", err) + return + } + + c.mu.Lock() + defer c.mu.Unlock() + + c.trunc() + fmt.Print("\033[37m") + fmt.Print("\rFrom: ") + fmt.Print("\033[0m") // unset color choice + fmt.Println(string(from)) + fmt.Print("\033[90m# ") + fmt.Println("--------------------------------------------------------------------------------") + fmt.Printf("\033[0m") + fmt.Println(string(text)) + c.renderLine() +} + func (c *Client) readTextBlock() ([]rune, error) { // god dammit what have i gotten myself into msg := make([]rune, 0, 400) diff --git a/message.go b/message.go new file mode 100644 index 0000000..62b14fb --- /dev/null +++ b/message.go @@ -0,0 +1,42 @@ +package main + +import () + +type Message struct { + Key []byte + From []byte + To string + Text []byte +} + +func (m Message) Kind() string { + return "message" +} + +type ListMessages struct { + N int +} + +func (l ListMessages) Kind() string { + return "list-messages" +} + +type ListMessagesResponseItem struct { + Id int + Key []byte + From []byte +} + +type ListMessagesResponse []ListMessagesResponseItem + +func (l ListMessagesResponse) Kind() string { + return "list-messages-response" +} + +type GetMessage struct { + Id int +} + +func (g GetMessage) Kind() string { + return "get-message" +} diff --git a/server.go b/server.go index 8beb82e..b98edc2 100644 --- a/server.go +++ b/server.go @@ -54,6 +54,8 @@ func (s *serverConnection) handleRequest(request Envelope) error { return s.handleKeyRequest(request.Id, request.Body) case "message": return s.handleMessageRequest(request.Id, request.Body) + case "get-message": + return s.handleGetMessageRequest(request.Id, request.Body) case "list-messages": return s.handleListMessagesRequest(request.Id, request.Body) default: @@ -235,6 +237,25 @@ func (s *serverConnection) handleMessageRequest(requestId int, body json.RawMess return s.sendResponse(requestId, Bool(true)) } +func (s *serverConnection) handleGetMessageRequest(requestId int, body json.RawMessage) error { + var req GetMessage + if err := json.Unmarshal(body, &req); err != nil { + return fmt.Errorf("unable to read getmessage request: %v", err) + } + + key := fmt.Sprintf("messages/%s", encodeInt(req.Id)) + val, err := s.db.Get([]byte(key), nil) + if err != nil { + return fmt.Errorf("unable to read message: %v", err) + } + + var msg Message + if err := json.Unmarshal(val, &msg); err != nil { + return fmt.Errorf("unable to parse message: %v", err) + } + return s.sendResponse(requestId, msg) +} + func (s *serverConnection) handleListMessagesRequest(requestId int, body json.RawMessage) error { var req ListMessages if err := json.Unmarshal(body, &req); err != nil {