func tableToMessage(L *lua.LState, t *lua.LTable) sarif.Message { msg := sarif.Message{} msg.Version = tableGetString(t, "sarif") msg.Id = tableGetString(t, "id") msg.Action = tableGetString(t, "action") msg.Source = tableGetString(t, "src") msg.Destination = tableGetString(t, "dest") msg.CorrId = tableGetString(t, "corr") msg.Text = tableGetString(t, "text") p := luareflect.DecodeToBasic(t.RawGetH(lua.LString("p"))) msg.EncodePayload(p) return msg }
func (cv *Conversation) SendToClient(msg sarif.Message) { // Save conversation. cv.LastTime = time.Now() cv.LastMessage = msg // Analyze message for possible user actions cv.LastMessageAction = Actionable{} msg.DecodePayload(&cv.LastMessageAction) msg = cv.service.AnnotateReply(msg) // Forward response to client. msg.Id = sarif.GenerateId() msg.Destination = cv.Device cv.service.Publish(msg) }
func (s *Server) handleRestPublish(w http.ResponseWriter, req *http.Request) { defer req.Body.Close() s.Client.Log("debug", "new REST request: "+req.URL.Path) // Parse form values. if err := req.ParseForm(); err != nil { s.Client.Log("warn", "REST bad request: "+err.Error()) w.WriteHeader(400) fmt.Fprintln(w, "Bad request:", err) return } // Check authentication. name := s.checkAuthentication(req) if name == "" { w.WriteHeader(401) fmt.Fprintln(w, "Not authorized") s.Client.Log("info", "authentication failed for "+req.RemoteAddr) return } s.Client.Log("info", "authenticated "+req.RemoteAddr+" for "+name) client := s.getApiClientByName(name) // Create message from form values. msg := sarif.Message{ Id: sarif.GenerateId(), Source: name, } if strings.HasPrefix(req.URL.Path, REST_URL) { msg.Action = strings.TrimPrefix(req.URL.Path, REST_URL) } pl := make(map[string]interface{}) for k, v := range req.Form { if k == "authtoken" { continue } if k == "_device" { msg.Destination = v[0] } else if k == "text" { msg.Text = strings.Join(v, "\n") } else if len(v) == 1 { pl[k] = parseValue(v[0]) } else if k == "_device" { pl[k] = v } } _ = msg.EncodePayload(pl) if !s.clientIsAllowed(name, msg) { w.WriteHeader(401) fmt.Fprintf(w, "'%s' is not authorized to publish '%s'", name, msg.Action) s.Client.Log("warn", "REST '"+name+"' is not authorized to publish on "+msg.Action) return } // Publish message. if err := client.Publish(msg); err != nil { s.Client.Log("warn", "REST bad request: "+err.Error()) w.WriteHeader(400) fmt.Fprintln(w, "Bad Request:", err) return } w.Write([]byte(msg.Id)) }
func ParseSimple(text string) (sarif.Message, bool) { msg := sarif.Message{} // Raw JSON message if strings.HasPrefix(text, "{") { if err := json.Unmarshal([]byte(text), &msg); err == nil { return msg, true } } if strings.HasPrefix(text, "sarif://") { if msg, err := sarif.ConvertURL(text); err == nil { return msg, true } } if strings.HasPrefix(text, ".") || strings.HasPrefix(text, "/") { text = strings.TrimLeft(text, "./ ") parts, _ := SplitQuoted(text, " ") if parts[0] == "" { return msg, false } msg.Action = parts[0] msg.Text = "" payload := make(map[string]interface{}, 0) for _, part := range parts[1:] { keyval, _ := SplitQuoted(part, "=") if len(keyval) == 1 { if msg.Text != "" { msg.Text += " " } msg.Text += TrimQuotes(keyval[0]) continue } k := TrimQuotes(keyval[0]) vtext := strings.Join(keyval[1:], "=") quoted := strings.ContainsAny(vtext, "\"`") vtext = TrimQuotes(vtext) var v interface{} = vtext if !quoted { v = ParseValue(vtext) } switch k { case "text": msg.Text = vtext case "device": fallthrough case "destination": msg.Destination = vtext default: payload[k] = v } } if len(payload) > 0 { msg.EncodePayload(payload) } return msg, true } return msg, false }