Ver código fonte

Server updates

Min 6 anos atrás
pai
commit
30a54371a7
9 arquivos alterados com 135 adições e 28 exclusões
  1. 18 5
      server/config.go
  2. 18 11
      server/inteface.go
  3. BIN
      server/server
  4. 53 2
      server/server.go
  5. 1 1
      server/templates/boards.pug
  6. 31 7
      server/templates/head.pug
  7. 12 0
      server/templates/logs.pug
  8. 0 0
      tutils.c
  9. 2 2
      utils.h

+ 18 - 5
server/config.go

@@ -10,18 +10,31 @@ import (
 )
 
 var configFile = "config.json"
+var defaultAdmin = &configAdmin{
+	"admin", []byte("$2a$14$iAOnPBQp6rlPIMGmTzH8qef1pK6tgl9yIfSLlZ2Z9IzIYn6hQPawi"),
+}
+
 var config = &configMain{
-	Admins: map[string]configAdmin{
-		"admin": {"admin", []byte("$2a$14$iAOnPBQp6rlPIMGmTzH8qef1pK6tgl9yIfSLlZ2Z9IzIYn6hQPawi")},
+	Admins: map[string]*configAdmin{
+		"admin": defaultAdmin,
 	},
-	Boards: map[uint16]configBoard{},
+	Boards: map[uint16]*configBoard{},
 	Secret: RandString(24),
+	Influx: nil,
+}
+
+type configInflux struct {
+	Domain string	`json:"domain"`
+	Database string `json:"database"`
+	Username string `json:"username"`
+	Password string `json:"password"`
 }
 
 type configMain struct{
-	Admins map[string]configAdmin `json:"admins"`
-	Boards map[uint16]configBoard `json:"boards"`
+	Admins map[string]*configAdmin `json:"admins"`
+	Boards map[uint16]*configBoard `json:"boards"`
 	Secret string `json:"secret"`
+	Influx *configInflux `json:"influx"`
 }
 
 type configAdmin struct{

+ 18 - 11
server/inteface.go

@@ -26,7 +26,7 @@ func genConfig() *userConfig {
 		make([]configBoard, 0, len(config.Boards)),
 	}
 	for k := range config.Admins { u.Admins = append(u.Admins, k) }
-	for b := range config.Boards { u.Boards = append(u.Boards, config.Boards[b]) }
+	for b := range config.Boards { u.Boards = append(u.Boards, *config.Boards[b]) }
 	return u
 }
 
@@ -34,10 +34,6 @@ func serveIndex(c echo.Context) error {
 	return c.File("server/templates/head.html")
 }
 
-func serveLogin(c echo.Context) error {
-	return c.File("server/templates/login.html")
-}
-
 func serveInterface(address string) {
 	e := echo.New()
 
@@ -52,7 +48,13 @@ func serveInterface(address string) {
 		return c.Redirect(http.StatusTemporaryRedirect, "/login")
 	})
 
-	e.GET("/login", serveLogin)
+	e.GET("/login", func(c echo.Context) error {
+		sess, _ := session.Get("session", c)
+		if auth, ok := sess.Values["authorised"]; ok && auth.(bool) {
+			return c.Redirect(http.StatusTemporaryRedirect, "/admin")
+		}
+		return c.File("server/templates/login.html")
+	})
 	g := e.Group("/admin")
 
 	g.Use(func(next echo.HandlerFunc) echo.HandlerFunc  {
@@ -60,10 +62,8 @@ func serveInterface(address string) {
 			sess, _ := session.Get("session", c)
 			auth, ok := sess.Values["authorised"]
 			if !ok || !auth.(bool) {
-				fmt.Println("Not authorised")
 				return c.Redirect(http.StatusTemporaryRedirect, "/login")
 			}
-			fmt.Println("Authorised")
 			return next(c)
 		}
 	})
@@ -104,7 +104,7 @@ func serveInterface(address string) {
 				fmt.Printf("Failed hash password %s\n", err)
 				return c.String(http.StatusNotAcceptable, "Failed to hash")
 			}
-			config.Admins[name] = admin
+			config.Admins[name] = &admin
  		}
 
 		saveConfig()
@@ -120,7 +120,8 @@ func serveInterface(address string) {
 		if err != nil || (keysize != 128 && keysize != 192 && keysize != 256) {
 			return c.String(http.StatusNotAcceptable, "Invalid key size")
 		}
-		key, err := hex.DecodeString(c.FormValue("key"))
+		keystr := strings.Trim(c.FormValue("key"), " ")
+		key, err := hex.DecodeString(keystr)
 		if err != nil {
 			return c.String(http.StatusNotAcceptable, "Key is not base 16")
 		}
@@ -141,7 +142,7 @@ func serveInterface(address string) {
 				_, err = rand.Read(key)
 				errCheck(err, "Failed generate random key")
 			}
-			config.Boards[id] = configBoard{
+			config.Boards[id] = &configBoard{
 				id,
 				key,
 				hex.EncodeToString(key),
@@ -185,8 +186,10 @@ func serveInterface(address string) {
 		password := c.FormValue("password")
 		user, ok := config.Admins[username]
 		if !ok || !user.checkPassword(password) {
+			e.Logger.Printf("User %s failed to login\n", username)
 			return c.File("server/templates/login.html")
 		}
+		e.Logger.Printf("User %s successfully logged in\n", username)
 		sess, _ := session.Get("session", c)
 		sess.Options = &sessions.Options{
 			Path:     "/",
@@ -208,6 +211,10 @@ func serveInterface(address string) {
 		return c.Redirect(http.StatusTemporaryRedirect, "/login")
 	})
 
+	g.GET("/logs", func(c echo.Context) error {
+		return c.JSON(http.StatusOK, &serverLogs)
+	})
+
 	//g.Use(middleware.BasicAuth()
 	g.GET("/config", func(c echo.Context) error {
 		return c.JSON(http.StatusOK, genConfig())

BIN
server/server


+ 53 - 2
server/server.go

@@ -3,16 +3,55 @@ package main
 import (
 	"crypto/aes"
 	"crypto/cipher"
+	"encoding/base64"
 	"encoding/binary"
 	"fmt"
+	"github.com/imroc/req"
 	"net"
 	"time"
 )
 
+type serverLog struct {
+	ID uint16			`json:"id"`
+	Stamp time.Time		`json:"stamp"`
+	Log string			`json:"log"`
+}
+
+type serverMsg struct {
+	id uint16
+	acc uint32
+	light bool
+}
 
+var serverLogs = []serverLog{{0, time.Now(), "Server started..."}}
+
+func sendData(msg *serverMsg) {
+	defer logPanic()
+	c := config.Influx
+	if c == nil {
+		return
+	}
+	var light int
+	if light = 0; msg.light { light = 1 }
+	now := time.Now().UnixNano()
+	data := fmt.Sprintf("accelerometer,board=%d value=%d %d\n", msg.id, msg.acc, now)
+	data += fmt.Sprintf("light,board=%d value=%d %d", msg.id, light, now)
+	auth := base64.StdEncoding.EncodeToString([]byte(c.Username+":"+c.Password))
+	head := req.Header{
+		"Authorization": "Basic " + auth,
+	}
+	r, err := req.Post(fmt.Sprintf("http://%s/write?db=%s", c.Domain, c.Database), head, data)
+	if err != nil {
+		errCheckPanic(err, "Failed send to influx server")
+	}
+	if r.Response().StatusCode > 300 {
+		fmt.Printf("Influx server returned code %d\n", r.Response().StatusCode)
+	}
+}
 
 func serveConnection(conn net.Conn) {
 	defer logPanic()
+	defer fmt.Printf("Connection closed %s\n", conn.RemoteAddr().String())
 	defer conn.Close()
 	fmt.Printf("Connection from %s\n", conn.RemoteAddr().String())
 	buf := make([]byte, 4)
@@ -23,7 +62,7 @@ func serveConnection(conn net.Conn) {
 
 		board, ok := config.Boards[id]
 		if !ok {
-			fmt.Printf("Connection with ID %d is not registerd", id)
+			fmt.Printf("Connection with ID %d is not registerd\n", id)
 			break
 		}
 		board.LastSeen = time.Now()
@@ -40,7 +79,19 @@ func serveConnection(conn net.Conn) {
 		errCheckPanic(err, "Decryption failed %s device #%d", conn.RemoteAddr().String(), id)
 		mode := cipher.NewCBCDecrypter(block, payload[:16])
 		mode.CryptBlocks(message, payload[16:])
-		fmt.Printf("Message: %s\n", string(message))
+		fmt.Printf("Message: %x\n", message)
+		msg := serverMsg{
+			id,
+			binary.LittleEndian.Uint32(message[:4]),
+			message[4] != 0x00,
+		}
+		sendData(&msg)
+		smessage := fmt.Sprintf("ACC: %d, LIGHT: %t", msg.acc, msg.light)
+		serverLogs = append([]serverLog{{id, board.LastSeen, smessage}}, serverLogs...)
+		if len(serverLogs) > 150 {
+			serverLogs = serverLogs[:len(serverLogs)-1]
+		}
+		fmt.Printf("Message: %x\n%s\n", message, smessage)
 	}
 
 }

+ 1 - 1
server/templates/boards.pug

@@ -20,7 +20,7 @@ h1.title Boards
                 .field
                     label.label Key (in base16)
                     .control
-                        input.input(type="text" v-model="admin.new_key")
+                        input.input(type="text" v-model="board.new_key")
                 p.help Leave empty for random
                 .field
                     .control

+ 31 - 7
server/templates/head.pug

@@ -24,6 +24,8 @@ html(lang='en')
                     include admins
                 template(v-else-if="menu_selected === 'boards'")
                     include boards
+                template(v-else-if="menu_selected === 'logs'")
+                    include logs
                 template(v-else)
                     include index
 
@@ -36,7 +38,7 @@ html(lang='en')
               app.error = response.data;
               return Promise.reject(response);
             } else if (response.status == 307 || response.status == 306) {
-              console.log(response);
+              // console.log(response);
             }
             return response;
           }, function (error) {
@@ -46,14 +48,23 @@ html(lang='en')
           var app = new Vue({
             el: '#app',
             data: {
-              menus: ['index', 'boards', 'admins'],
+              menus: ['index', 'boards', 'admins', 'logs'],
               menu_selected: 'index',
               config: {},
               admin: {new_user: "", new_pass: ""},
               board: {new_id: "", new_key: "", new_keysize: 128},
-              error: ""
+              error: "",
+              srvlogs: [],
+              log_timer: null
             },
             methods: {
+              get_logs: function() {
+                  let self = this;
+                  axios.get('/admin/logs').then(function (res) {
+                      self.srvlogs = res.data;
+                      self.log_timer = window.setTimeout(self.get_logs, 1500);
+                  })
+              },
               admin_delete: function(admin) {
                 let self = this;
                 axios.delete('/admin/user/' + admin).then(function (res) {
@@ -95,15 +106,28 @@ html(lang='en')
                 self.config = res.data;
               })
             },
+            watch: {
+              menu_selected: function (now, old) {
+                let self = this;
+                if (now === old) return;
+                if (now==="logs") {
+                    console.log("Timer ready");
+                    self.get_logs();
+                } else {
+                    console.log("Timer removed");
+                    window.clearTimeout(self.log_timer);
+                }
+              }
+            },
             filters: {
               timeSince: function (datestr) {
-                if (datestr === "0001-01-01T00:00:00Z") return "never";
+                if (datestr === "0001-01-01T00:00:00Z" || datestr === "1970-01-01T01:00:00+01:00") return "never";
                 let date = new Date(datestr);
                 let delta = new Date() - date;
                 if (delta > 1000*60*60*24) {
-                  let year = d.getFullYear();
-                  let month = '' + (d.getMonth() + 1);
-                  let day = '' + d.getDate();
+                  let year = date.getFullYear();
+                  let month = '' + (date.getMonth() + 1);
+                  let day = '' + date.getDate();
                   if (month.length < 2) month = '0' + month;
                   if (day.length < 2) day = '0' + day;
                   return [year, month, day].join('/');

+ 12 - 0
server/templates/logs.pug

@@ -0,0 +1,12 @@
+h1.title Logs
+table.table.is-striped.is-hoverable.is-fullwidth
+    thead
+        tr
+            th ID
+            th Stamp
+            th Message
+    tbody
+        tr(v-for="x in srvlogs")
+            td {{ x.id }}
+            td {{ x.stamp }}
+            td {{ x.log }}

utils.c → tutils.c


+ 2 - 2
utils.h

@@ -1,6 +1,6 @@
 
-#ifndef __ELEC0017_CRYPTO_H__
-#define __ELEC0017_CRYPTO_H__
+#ifndef __ELEC0017_UTILS_H__
+#define __ELEC0017_UTILS_H__
 
 #ifdef __cplusplus
 extern "C"