Example #1
0
func (s *Service) handleAuthToken(msg sarif.Message) {
	tok := "token/std:" + sarif.GenerateId() + sarif.GenerateId() + sarif.GenerateId()
	s.Config.Tokens[tok] = true
	s.cfg.Set(s.Config)

	s.Reply(msg, sarif.CreateMessage("auth/generated", sarif.ClientInfo{
		Auth: tok,
	}))
}
Example #2
0
func New() *App {
	var err error
	log.SetFlags(0)
	app := &App{
		App: core.NewApp("sarif", "tars"),
	}
	app.Init()
	app.Client, err = app.ClientDial(sarif.ClientInfo{
		Name: "tars/" + sarif.GenerateId(),
		Auth: *authString,
	})
	app.Must(err)

	app.Config.HistoryFile = app.App.Config.Dir() + "/tars_history"
	app.App.Config.Get("tars", &app.Config)

	app.Commands = []Command{
		{"help", app.Help, ""},
		{"interactive", app.Interactive, ""},
		{"location_import", app.LocationImport, ""},
		{"cat", app.Cat, usageCat},
		{"down", app.Down, ""},
		{"up", app.Up, ""},
		{"edit", app.Edit, ""},
	}

	return app
}
Example #3
0
func (s *Service) handleLuaLoad(msg sarif.Message) {
	gen := false
	name := strings.TrimPrefix(strings.TrimPrefix(msg.Action, "lua/load"), "/")
	if name == "" {
		name, gen = sarif.GenerateId(), true
	}
	if _, ok := s.Machines[name]; ok {
		s.destroyMachine(name)
	}

	m, err := s.createMachine(name)
	if err != nil {
		s.ReplyInternalError(msg, err)
		return
	}

	var ctp ContentPayload
	if err := msg.DecodePayload(&ctp); err != nil {
		s.ReplyBadRequest(msg, err)
		return
	}
	text := msg.Text
	if ctp.Content.Url != "" {
		ct, err := content.Get(ctp.Content)
		if err != nil {
			s.ReplyBadRequest(msg, err)
		}
		text = string(ct.Data)
	}

	var gp interface{}
	msg.DecodePayload(&gp)
	out, err, _ := m.Do(text, gp)
	if err != nil {
		s.ReplyBadRequest(msg, err)
		s.destroyMachine(name)
		return
	}

	if !gen {
		f, err := os.Create(s.cfg.ScriptDir + "/" + name + ".lua")
		if err == nil {
			_, err = f.Write([]byte(text))
			defer f.Close()
		}
		if err != nil {
			s.ReplyInternalError(msg, err)
			s.destroyMachine(name)
			return
		}
	}

	s.Reply(msg, sarif.CreateMessage("lua/loaded", &MsgMachineStatus{
		name,
		"up",
		out,
	}))
}
Example #4
0
func (app *App) Interactive() {
	rl, err := readline.NewEx(&readline.Config{
		Prompt:      color.BlueString("say » "),
		HistoryFile: app.Config.HistoryFile,
	})
	if err != nil {
		log.Fatal(err)
	}
	defer rl.Close()
	app.Log.SetOutput(rl.Stderr())
	log.SetOutput(rl.Stderr())
	color.Output = ansicolor.NewAnsiColorWriter(rl.Stderr())

	pings := make(map[string]time.Time)

	// Subscribe to all replies and print them to stdout
	app.Client.Subscribe("", "self", func(msg sarif.Message) {
		text := msg.Text
		if text == "" {
			text = msg.Action + " from " + msg.Source
		}
		if msg.IsAction("err") {
			text = color.RedString(text)
		}

		if sent, ok := pings[msg.CorrId]; ok {
			text += color.YellowString("[%.1fms]", time.Since(sent).Seconds()*1e3)
		}
		log.Println(color.GreenString(" « ") + strings.Replace(text, "\n", "\n   ", -1))
	})

	// Interactive mode sends all lines from stdin.
	for {
		line, err := rl.Readline()
		if err != nil {
			if err == io.EOF {
				return
			}
			log.Fatal(err)
		}
		if len(line) == 0 {
			continue
		}

		// Publish natural message
		msg := sarif.Message{
			Id:     sarif.GenerateId(),
			Action: "natural/handle",
			Text:   line,
		}
		if *profile {
			pings[msg.Id] = time.Now()
		}
		app.Client.Publish(msg)
	}
}
Example #5
0
func NewTestRunner(t *testing.T) *TestRunner {
	return &TestRunner{
		T:           t,
		WaitTimeout: time.Second,
		IgnoreSubs:  true,
		Id:          "testutils-" + sarif.GenerateId(),

		Received: make(chan sarif.Message, 5),
		RecMutex: sync.Mutex{},
	}
}
Example #6
0
func main() {
	addr := "tcp://localhost:23100"
	if len(os.Args) > 1 {
		addr = os.Args[1]
	}
	fmt.Println("connecting to", addr)

	// Setup our client.
	client := sarif.NewClient("sarifping")
	err := client.Dial(&sarif.NetConfig{
		Address: addr,
	})
	if err != nil {
		log.Fatal(err)
	}
	pings := make(map[string]time.Time)

	// Subscribe to all acknowledgements to our pings
	// and print them.
	client.Subscribe("ack", "self", func(msg sarif.Message) {
		if !msg.IsAction("ack") {
			return
		}
		sent, ok := pings[msg.CorrId]
		if !ok {
			return
		}

		fmt.Printf("%s from %s: time=%.1fms\n",
			msg.Action,
			msg.Source,
			time.Since(sent).Seconds()*1e3,
		)
	})

	// Every second, send a ping to all devices.
	for _ = range time.Tick(1 * time.Second) {
		// Create the ping message and publish it on the network
		msg := sarif.Message{
			Id:     sarif.GenerateId(),
			Action: "ping",
		}
		if err := client.Publish(msg); err != nil {
			log.Fatal(err)
		}
		pings[msg.Id] = time.Now()
	}
}
Example #7
0
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)
}
Example #8
0
func relay() {
	app := core.NewApp("sarif", "tars")
	app.Init()

	info := Cache{FilePath: app.Config.Dir() + "/soji.json"}
	info.Bars = make(map[string]Bar)
	info.Read()

	info.PID = os.Getpid()
	app.Must(info.Write())

	c, err := app.ClientDial(sarif.ClientInfo{
		Name: "soji/" + sarif.GenerateId(),
	})
	c.HandleConcurrent = false
	app.Must(err)

	c.Subscribe("status", "", func(msg sarif.Message) {
		key := msg.Action
		if strings.HasPrefix(key, "status/") {
			key = strings.TrimPrefix(key, "status/")
		} else {
			key = "default"
		}

		bar := Bar{Key: key, Label: key, Text: msg.Text}
		if err := msg.DecodePayload(&bar); err != nil {
			msg.DecodePayload(&bar.Text)
			msg.DecodePayload(&bar.Value)
		}

		info.Bars[bar.Key] = bar
		app.Must(info.Write())
	})

	fmt.Println(os.Getpid())
	core.WaitUntilInterrupt()

	info.PID = 0
	app.Must(info.Write())

	c.Publish(sarif.CreateMessage("soji/down", nil))
}
Example #9
0
func (s *Service) createMachine(name string) (*Machine, error) {
	if name == "" {
		name = sarif.GenerateId()
	}
	if _, ok := s.Machines[name]; ok {
		return nil, errors.New("Machine " + name + " already exists")
	}

	c := sarif.NewClient(s.DeviceId + "/" + name)
	c.Connect(s.Broker.NewLocalConn())

	m := NewMachine(c)
	s.Machines[name] = m
	if listeners, ok := s.Listeners[name]; ok {
		for _, l := range listeners {
			m.Attach(l)
		}
	}
	if err := m.Enable(); err != nil {
		return m, err
	}
	return m, nil
}
Example #10
0
func (s *Service) handleGeofenceCreate(msg sarif.Message) {
	var g Geofence
	if err := msg.DecodePayload(&g); err != nil {
		s.ReplyBadRequest(msg, err)
		return
	}

	if g.Address != "" {
		geo, err := Geocode(g.Address)
		if err != nil {
			s.ReplyBadRequest(msg, err)
			return
		}
		if len(geo) == 0 {
			s.Publish(msg.Reply(MsgAddressNotFound))
			return
		}
		g.BoundingBox = BoundingBox(geo[0].BoundingBox)
	}
	if g.Name == "" {
		g.Name = sarif.GenerateId()
	}
	g.GeohashMin = EncodeGeohash(g.BoundingBox.LatMin, g.BoundingBox.LngMin, 12)
	g.GeohashMax = EncodeGeohash(g.BoundingBox.LatMax, g.BoundingBox.LngMax, 12)

	if _, err := s.Store.Put(g.Key(), &g); err != nil {
		s.ReplyInternalError(msg, err)
	}

	reply := sarif.Message{Action: "location/fence/created"}
	if err := reply.EncodePayload(g); err != nil {
		s.ReplyInternalError(msg, err)
		return
	}
	reply.Text = "Geofence '" + g.Name + "' created."
	s.Publish(reply)
}
Example #11
0
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))
}