From 5548949e9dc161e823a8c7e1dcce67a7dabed592 Mon Sep 17 00:00:00 2001 From: Joerg Lehmann Date: Thu, 9 Apr 2020 14:41:41 +0200 Subject: [PATCH] go fmt; email message after payment --- authentication.go | 41 ++-- helper.go | 18 +- log.go | 2 +- mail.go | 82 +++---- main.go | 80 +++---- metrics.go | 583 +++++++++++++++++++++++----------------------- persistence.go | 412 ++++++++++++++++---------------- scales.go | 176 +++++++------- stripe.go | 192 +++++++-------- 9 files changed, 791 insertions(+), 795 deletions(-) diff --git a/authentication.go b/authentication.go index efc4b70..e018182 100644 --- a/authentication.go +++ b/authentication.go @@ -1,11 +1,11 @@ package main import ( + "crypto/md5" + "encoding/hex" + "fmt" "github.com/gorilla/securecookie" "net/http" - "fmt" - "crypto/md5" - "encoding/hex" ) // cookie handling @@ -31,9 +31,9 @@ func getUserNameHash(request *http.Request) (userName string) { userName = cookieValue["name"] } } - hasher := md5.New() - hasher.Write([]byte(userName)) - return hex.EncodeToString(hasher.Sum(nil)) + hasher := md5.New() + hasher.Write([]byte(userName)) + return hex.EncodeToString(hasher.Sum(nil)) } func setSession(userName string, response http.ResponseWriter) { @@ -67,34 +67,33 @@ func loginHandler(response http.ResponseWriter, request *http.Request) { pass := request.FormValue("password") redirectTarget := "/invalid_login.html" // .. check credentials .. - if checkLoginCredentials(name,pass) { + if checkLoginCredentials(name, pass) { redirectTarget = "/scales.html" - logit(fmt.Sprintf("loginHandler: successful login for User %s",name)) + logit(fmt.Sprintf("loginHandler: successful login for User %s", name)) setSession(name, response) updateLoginTime(name) } else { - logit(fmt.Sprintf("loginHandler: invalid login for User %s",name)) - } + logit(fmt.Sprintf("loginHandler: invalid login for User %s", name)) + } http.Redirect(response, request, redirectTarget, 302) } - // resetPassword handler func resetPasswordHandler(response http.ResponseWriter, request *http.Request) { name := request.FormValue("email") pass := request.FormValue("password") redirectTarget := "/" - logit(fmt.Sprintf("resetPasswordHandler: request for User %s",name)) + logit(fmt.Sprintf("resetPasswordHandler: request for User %s", name)) if name != "" && pass != "" { if checkUserAvailable(name) { - http.Redirect(response, request, "/user_does_not_exist.html", 302) + http.Redirect(response, request, "/user_does_not_exist.html", 302) } else { - updateUser(name,pass) - http.Redirect(response, request, redirectTarget, 302) - } + updateUser(name, pass) + http.Redirect(response, request, redirectTarget, 302) + } } - http.Redirect(response, request, "/error_reset_password.html",302) + http.Redirect(response, request, "/error_reset_password.html", 302) } // setPassword handler @@ -104,10 +103,10 @@ func setPasswordHandler(response http.ResponseWriter, request *http.Request) { pass := request.FormValue("password") if name != "" && pass != "" { if checkUserAvailable(name) { - http.Redirect(response, request, "/user_does_not_exist.html", 302) + http.Redirect(response, request, "/user_does_not_exist.html", 302) } else { - updateUser(name,pass) - } + updateUser(name, pass) + } } } @@ -122,7 +121,7 @@ func logoutHandler(response http.ResponseWriter, request *http.Request) { func confirmHandler(response http.ResponseWriter, request *http.Request) { confirm_id := request.URL.Query().Get("id") - logit(fmt.Sprintf("Confirm ID: %s\n",confirm_id)) + logit(fmt.Sprintf("Confirm ID: %s\n", confirm_id)) confirmUser(confirm_id) http.Redirect(response, request, "/", 302) } diff --git a/helper.go b/helper.go index d04795b..e21f3ed 100644 --- a/helper.go +++ b/helper.go @@ -1,17 +1,17 @@ package main import ( - "log" + "log" ) // Contains tells whether a contains x. func Contains(a []string, x string) bool { - log.Println("Search for: "+x) - for _, n := range a { - log.Println("Piece of Array: "+n) - if x == n { - return true - } - } - return false + log.Println("Search for: " + x) + for _, n := range a { + log.Println("Piece of Array: " + n) + if x == n { + return true + } + } + return false } diff --git a/log.go b/log.go index 5a97791..f8a91ac 100644 --- a/log.go +++ b/log.go @@ -5,5 +5,5 @@ import ( ) func logit(log_message string) { - log.Println(log_message) + log.Println(log_message) } diff --git a/mail.go b/mail.go index 20d081e..e500ae9 100644 --- a/mail.go +++ b/mail.go @@ -1,26 +1,26 @@ package main import ( - "log" "bytes" + "log" "net/smtp" ) -func sendEmail(username,confirm_id string) { - c, err := smtp.Dial("127.0.0.1:25") - if err != nil { - log.Fatal(err) - } - defer c.Close() - // Set the sender and recipient. - c.Mail("register@mini-beieli.ch") - c.Rcpt(username) - // Send the email body. - wc, err := c.Data() - if err != nil { - log.Fatal(err) - } - defer wc.Close() +func sendEmail(username, confirm_id string) { + c, err := smtp.Dial("127.0.0.1:25") + if err != nil { + log.Fatal(err) + } + defer c.Close() + // Set the sender and recipient. + c.Mail("register@mini-beieli.ch") + c.Rcpt(username) + // Send the email body. + wc, err := c.Data() + if err != nil { + log.Fatal(err) + } + defer wc.Close() mail_message := "To: " + username + ` Subject: Passwortaenderung auf https://mini-beieli.ch, bitte bestaetigen @@ -37,27 +37,27 @@ Mit freundlichen Grüssen -- mini-beieli.ch` - buf := bytes.NewBufferString(mail_message) - if _, err = buf.WriteTo(wc); err != nil { - log.Fatal(err) - } -} + buf := bytes.NewBufferString(mail_message) + if _, err = buf.WriteTo(wc); err != nil { + log.Fatal(err) + } +} -func sendPaymentConfirmationEmail(username,charge_data string, amount int64) { - c, err := smtp.Dial("127.0.0.1:25") - if err != nil { - log.Fatal(err) - } - defer c.Close() - // Set the sender and recipient. - c.Mail("info@mini-beieli.ch") - c.Rcpt(username) - // Send the email body. - wc, err := c.Data() - if err != nil { - log.Fatal(err) - } - defer wc.Close() +func sendPaymentConfirmationEmail(username, charge_data string, amount int64) { + c, err := smtp.Dial("127.0.0.1:25") + if err != nil { + log.Fatal(err) + } + defer c.Close() + // Set the sender and recipient. + c.Mail("info@mini-beieli.ch") + c.Rcpt(username) + // Send the email body. + wc, err := c.Data() + if err != nil { + log.Fatal(err) + } + defer wc.Close() mail_message := "To: " + username + ` Subject: Zahlungsbestaetigung mini-beieli.ch @@ -71,8 +71,8 @@ Mit freundlichen Grüssen -- mini-beieli.ch` - buf := bytes.NewBufferString(mail_message) - if _, err = buf.WriteTo(wc); err != nil { - log.Fatal(err) - } -} + buf := bytes.NewBufferString(mail_message) + if _, err = buf.WriteTo(wc); err != nil { + log.Fatal(err) + } +} diff --git a/main.go b/main.go index 6b5bc1d..01e7bd8 100644 --- a/main.go +++ b/main.go @@ -5,11 +5,11 @@ import ( "net/http" "os" "path" - "time" + "time" ) func serveTemplate(w http.ResponseWriter, r *http.Request) { - logit("Called URL: "+r.URL.Path) + logit("Called URL: " + r.URL.Path) // wennn kein File angegeben ist: index.html if r.URL.Path == "/" { r.URL.Path = "/index.html" @@ -35,36 +35,36 @@ func serveTemplate(w http.ResponseWriter, r *http.Request) { return } - var userName = getUserName(r) + var userName = getUserName(r) - t := time.Now() - var datetimestring = t.Format("20060102150405") - var scales = getMyDevs(userName) - var last_metrics []OneMetric - - query_values := r.URL.Query() + t := time.Now() + var datetimestring = t.Format("20060102150405") + var scales = getMyDevs(userName) + var last_metrics []OneMetric - if (r.URL.Path == "/scales.html") { - // wir holen noch die letzten Metriken - for _, v := range scales { - last_metric := getLastMetrics(v) - last_metrics = append(last_metrics, last_metric) - } + query_values := r.URL.Query() + + if r.URL.Path == "/scales.html" { + // wir holen noch die letzten Metriken + for _, v := range scales { + last_metric := getLastMetrics(v) + last_metrics = append(last_metrics, last_metric) + } } - data := struct { - UserName string - DateTimeString string - Scales []string - LastMetrics []OneMetric - QueryValues map[string][]string - } { - userName, - datetimestring, - scales, - last_metrics, - query_values, - } + data := struct { + UserName string + DateTimeString string + Scales []string + LastMetrics []OneMetric + QueryValues map[string][]string + }{ + userName, + datetimestring, + scales, + last_metrics, + query_values, + } if err := tmpl.ExecuteTemplate(w, "layout", &data); err != nil { logit(err.Error()) @@ -73,23 +73,23 @@ func serveTemplate(w http.ResponseWriter, r *http.Request) { } func main() { - initDB() - defer closeDB() + initDB() + defer closeDB() fs := http.FileServer(http.Dir("static")) http.Handle("/static/", http.StripPrefix("/static/", fs)) http.Handle("/favicon.ico", fs) http.HandleFunc("/", serveTemplate) - http.HandleFunc("/login", loginHandler) - http.HandleFunc("/reset_password", resetPasswordHandler) - http.HandleFunc("/set_password", setPasswordHandler) - http.HandleFunc("/logout", logoutHandler) - http.HandleFunc("/confirm", confirmHandler) - http.HandleFunc("/metrics", metricsHandler) - http.HandleFunc("/lastmetrics", lastmetricsHandler) - http.HandleFunc("/save_scale_settings", save_scale_settingsHandler) - http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler) - http.HandleFunc("/stripewebhook", stripeWebhookHandler) + http.HandleFunc("/login", loginHandler) + http.HandleFunc("/reset_password", resetPasswordHandler) + http.HandleFunc("/set_password", setPasswordHandler) + http.HandleFunc("/logout", logoutHandler) + http.HandleFunc("/confirm", confirmHandler) + http.HandleFunc("/metrics", metricsHandler) + http.HandleFunc("/lastmetrics", lastmetricsHandler) + http.HandleFunc("/save_scale_settings", save_scale_settingsHandler) + http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler) + http.HandleFunc("/stripewebhook", stripeWebhookHandler) logit("Starting Web Application...") http.ListenAndServe("127.0.0.1:4000", nil) diff --git a/metrics.go b/metrics.go index 9bc1056..bade870 100644 --- a/metrics.go +++ b/metrics.go @@ -1,355 +1,354 @@ package main import ( - "bytes" - "fmt" - "log" - "net/http" - "time" - "io/ioutil" - "bufio" - "strings" - "strconv" + "bufio" + "bytes" + "fmt" + "io/ioutil" + "log" + "net/http" + "strconv" + "strings" + "time" ) type OneMetric struct { - Deveui string - Alias string - Alarmactive string - Smsnumber string - Timestamp string - Temperature string - Humidity string - Weight string - Weight_kg string - Pressure string - BatteryPercent string - ActiveUntil string - DaysUntilDeactivated int // berechneter Wert + Deveui string + Alias string + Alarmactive string + Smsnumber string + Timestamp string + Temperature string + Humidity string + Weight string + Weight_kg string + Pressure string + BatteryPercent string + ActiveUntil string + DaysUntilDeactivated int // berechneter Wert } - // metrics handler func metricsHandler(response http.ResponseWriter, request *http.Request) { - name := getUserName(request) - if name != "" { + name := getUserName(request) + if name != "" { - property, ok := request.URL.Query()["property"] - if !ok || len(property[0]) < 1 { - log.Println("Url Param 'property' is missing") - fmt.Fprintf(response, "{ \"msg\": \"property must be specified in URL\" }") - return - } + property, ok := request.URL.Query()["property"] + if !ok || len(property[0]) < 1 { + log.Println("Url Param 'property' is missing") + fmt.Fprintf(response, "{ \"msg\": \"property must be specified in URL\" }") + return + } - deveui, ok := request.URL.Query()["deveui"] + deveui, ok := request.URL.Query()["deveui"] - if !ok || len(deveui[0]) < 1 { - log.Println("Url Param 'deveui' is missing") - fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }") - return - } - // Query()["deveui"] will return an array of items, - // we only want the single item. - mydeveui := deveui[0] - - if !(Contains(getMyDevs(name),mydeveui)) { - log.Println("specified 'deveui' does not belong to this user") - fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }") - return - } + if !ok || len(deveui[0]) < 1 { + log.Println("Url Param 'deveui' is missing") + fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }") + return + } + // Query()["deveui"] will return an array of items, + // we only want the single item. + mydeveui := deveui[0] - if AboExpired(mydeveui) { - log.Println("specified 'deveui' has an expired abo") - fmt.Fprintf(response, "{ \"msg\": \"specified deveui has an expired abo\" }") - return - } + if !(Contains(getMyDevs(name), mydeveui)) { + log.Println("specified 'deveui' does not belong to this user") + fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }") + return + } - log.Println("Url Param 'deveui' is: " + string(mydeveui)) + if AboExpired(mydeveui) { + log.Println("specified 'deveui' has an expired abo") + fmt.Fprintf(response, "{ \"msg\": \"specified deveui has an expired abo\" }") + return + } - // Format of start and stop: YYYY-MM-DDTHH:MI:SSZ + log.Println("Url Param 'deveui' is: " + string(mydeveui)) - stop, ok := request.URL.Query()["stop"] - var mystop string - if !ok || len(stop[0]) < 1 { - log.Println("Url Param 'stop' is missing, set it to now") - mystop = time.Now().Format("2006-01-02T15:04:05Z") - } + // Format of start and stop: YYYY-MM-DDTHH:MI:SSZ - if ok { - mystop = stop[0] - } + stop, ok := request.URL.Query()["stop"] + var mystop string + if !ok || len(stop[0]) < 1 { + log.Println("Url Param 'stop' is missing, set it to now") + mystop = time.Now().Format("2006-01-02T15:04:05Z") + } - layout := "2006-01-02T15:04:05Z" - stopDate, err := time.Parse(layout, mystop) + if ok { + mystop = stop[0] + } - if err != nil { - fmt.Println(err) - } + layout := "2006-01-02T15:04:05Z" + stopDate, err := time.Parse(layout, mystop) - start, ok := request.URL.Query()["start"] - var mystart string - if !ok || len(start[0]) < 1 { - log.Println("Url Param 'start' is missing, set it to stop minus one day") - t := stopDate.AddDate(0,0,-1) - mystart = t.Format("2006-01-02T15:04:05Z") - } + if err != nil { + fmt.Println(err) + } - if ok { - mystart = start[0] - } + start, ok := request.URL.Query()["start"] + var mystart string + if !ok || len(start[0]) < 1 { + log.Println("Url Param 'start' is missing, set it to stop minus one day") + t := stopDate.AddDate(0, 0, -1) + mystart = t.Format("2006-01-02T15:04:05Z") + } - url := "http://localhost:9999/api/v2/query?org=beieliorg" - data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start: %s, stop: %s) |> filter(fn: (r) => r._measurement == "measurement") |> filter(fn: (r) => r._field == "%s") |> filter(fn: (r) => r.deveui == "%s")`,mystart,mystop,property[0],mydeveui)) + if ok { + mystart = start[0] + } - req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) - if err != nil { - log.Fatal("Error reading request. ", err) - } - - // Set headers - req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==") - req.Header.Set("accept", "application/csv") - req.Header.Set("content-type", "application/vnd.flux") - - // Set client timeout - client := &http.Client{Timeout: time.Second * 10} - - // Send request - resp, err := client.Do(req) - if err != nil { - log.Fatal("Error reading response. ", err) - } - defer resp.Body.Close() - - fmt.Println("response Status:", resp.Status) - fmt.Println("response Headers:", resp.Header) + url := "http://localhost:9999/api/v2/query?org=beieliorg" + data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start: %s, stop: %s) |> filter(fn: (r) => r._measurement == "measurement") |> filter(fn: (r) => r._field == "%s") |> filter(fn: (r) => r.deveui == "%s")`, mystart, mystop, property[0], mydeveui)) - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Fatal("Error reading body. ", err) - } - - fmt.Fprintf(response,"[\n") - scanner := bufio.NewScanner(strings.NewReader(string(body))) - first := true - for scanner.Scan() { - s := strings.Split(scanner.Text(),",") - if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) { - t,err := time.Parse(time.RFC3339,s[5]) - if err != nil { - continue - } - a := t.Unix() - b := s[6] - if !(first) { - fmt.Fprintf(response,",") - } else { - first = false - } - fmt.Fprintf(response,"[%d000,%s]\n",a,b) - } - } - fmt.Fprintf(response,"]\n") + req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) + if err != nil { + log.Fatal("Error reading request. ", err) + } - } else { - fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }") - } + // Set headers + req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==") + req.Header.Set("accept", "application/csv") + req.Header.Set("content-type", "application/vnd.flux") + + // Set client timeout + client := &http.Client{Timeout: time.Second * 10} + + // Send request + resp, err := client.Do(req) + if err != nil { + log.Fatal("Error reading response. ", err) + } + defer resp.Body.Close() + + fmt.Println("response Status:", resp.Status) + fmt.Println("response Headers:", resp.Header) + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatal("Error reading body. ", err) + } + + fmt.Fprintf(response, "[\n") + scanner := bufio.NewScanner(strings.NewReader(string(body))) + first := true + for scanner.Scan() { + s := strings.Split(scanner.Text(), ",") + if (len(s) >= 7) && !(strings.HasPrefix(s[5], "_")) { + t, err := time.Parse(time.RFC3339, s[5]) + if err != nil { + continue + } + a := t.Unix() + b := s[6] + if !(first) { + fmt.Fprintf(response, ",") + } else { + first = false + } + fmt.Fprintf(response, "[%d000,%s]\n", a, b) + } + } + fmt.Fprintf(response, "]\n") + + } else { + fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }") + } } func lastmetricsHandler(response http.ResponseWriter, request *http.Request) { - name := getUserName(request) - if name != "" { + name := getUserName(request) + if name != "" { - deveui, ok := request.URL.Query()["deveui"] + deveui, ok := request.URL.Query()["deveui"] - if !ok || len(deveui[0]) < 1 { - log.Println("Url Param 'deveui' is missing") - fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }") - return - } - // Query()["deveui"] will return an array of items, - // we only want the single item. - mydeveui := deveui[0] - - if !(Contains(getMyDevs(name),mydeveui)) { - log.Println("specified 'deveui' does not belong to this user") - fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }") - return - } + if !ok || len(deveui[0]) < 1 { + log.Println("Url Param 'deveui' is missing") + fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }") + return + } + // Query()["deveui"] will return an array of items, + // we only want the single item. + mydeveui := deveui[0] - log.Println("Url Param 'deveui' is: " + string(mydeveui)) + if !(Contains(getMyDevs(name), mydeveui)) { + log.Println("specified 'deveui' does not belong to this user") + fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }") + return + } - url := "http://localhost:9999/api/v2/query?org=beieliorg" - //data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-365d) |> filter(fn: (r) => r.deveui == "%s") |> filter(fn: (r) => r._field == "v" or r._field == "t") |> last() |> yield(name: "last")`,mydeveui)) - data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") + log.Println("Url Param 'deveui' is: " + string(mydeveui)) + + url := "http://localhost:9999/api/v2/query?org=beieliorg" + //data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-365d) |> filter(fn: (r) => r.deveui == "%s") |> filter(fn: (r) => r._field == "v" or r._field == "t") |> last() |> yield(name: "last")`,mydeveui)) + data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-365d) |> filter(fn: (r) => r.deveui == "%s") |> filter(fn: (r) => r._field == "t" or r._field == "h" or r._field == "w" or r._field == "p" or r._field == "vp") - |> last() |> yield(name: "last")`,mydeveui)) + |> last() |> yield(name: "last")`, mydeveui)) - req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) - if err != nil { - log.Fatal("Error reading request. ", err) - } - - // Set headers - req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==") - req.Header.Set("accept", "application/csv") - req.Header.Set("content-type", "application/vnd.flux") - - // Set client timeout - client := &http.Client{Timeout: time.Second * 10} - - // Send request - resp, err := client.Do(req) - if err != nil { - log.Fatal("Error reading response. ", err) - } - defer resp.Body.Close() - - fmt.Println("response Status:", resp.Status) - fmt.Println("response Headers:", resp.Header) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) + if err != nil { + log.Fatal("Error reading request. ", err) + } - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Fatal("Error reading body. ", err) - } - fmt.Println("response Body:", string(body)) - - scanner := bufio.NewScanner(strings.NewReader(string(body))) - ts := "" - t := "" - h := "" - w := "" - p := "" - vp := "" - location, err := time.LoadLocation("Europe/Zurich") - for scanner.Scan() { - s := strings.Split(scanner.Text(),",") - if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) { - mytime,err := time.Parse(time.RFC3339,s[5]) - if err != nil { - continue - } - ts = mytime.In(location).Format("02.01.2006 15:04") - value := s[6] - field := s[7] - if field == "t" { - t = value - } else if field == "h" { - h = value - } else if field == "w" { - w = value - } else if field == "p" { - p = value - } else if field == "vp" { - vp = value - } - } - } - fmt.Fprintf(response,`{ + // Set headers + req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==") + req.Header.Set("accept", "application/csv") + req.Header.Set("content-type", "application/vnd.flux") + + // Set client timeout + client := &http.Client{Timeout: time.Second * 10} + + // Send request + resp, err := client.Do(req) + if err != nil { + log.Fatal("Error reading response. ", err) + } + defer resp.Body.Close() + + fmt.Println("response Status:", resp.Status) + fmt.Println("response Headers:", resp.Header) + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatal("Error reading body. ", err) + } + fmt.Println("response Body:", string(body)) + + scanner := bufio.NewScanner(strings.NewReader(string(body))) + ts := "" + t := "" + h := "" + w := "" + p := "" + vp := "" + location, err := time.LoadLocation("Europe/Zurich") + for scanner.Scan() { + s := strings.Split(scanner.Text(), ",") + if (len(s) >= 7) && !(strings.HasPrefix(s[5], "_")) { + mytime, err := time.Parse(time.RFC3339, s[5]) + if err != nil { + continue + } + ts = mytime.In(location).Format("02.01.2006 15:04") + value := s[6] + field := s[7] + if field == "t" { + t = value + } else if field == "h" { + h = value + } else if field == "w" { + w = value + } else if field == "p" { + p = value + } else if field == "vp" { + vp = value + } + } + } + fmt.Fprintf(response, `{ "ts": "%s", "t": "%s", "h": "%s", "w": "%s", "p": "%s", "vp": "%s" -}`,ts,t,h,w,p,vp) +}`, ts, t, h, w, p, vp) - } else { - fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }") - } + } else { + fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }") + } } func CalcDaysUntil(mydate string) int { - var days int - layout := "02.01.2006" - t, err := time.Parse(layout, mydate) + var days int + layout := "02.01.2006" + t, err := time.Parse(layout, mydate) - if err != nil { - days = 0 - } - days = int(t.Sub(time.Now()).Hours() / 24) - - return days + if err != nil { + days = 0 + } + days = int(t.Sub(time.Now()).Hours() / 24) + + return days } func getLastMetrics(deveui string) OneMetric { - var res OneMetric + var res OneMetric - url := "http://localhost:9999/api/v2/query?org=beieliorg" - data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") + url := "http://localhost:9999/api/v2/query?org=beieliorg" + data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-365d) |> filter(fn: (r) => r.deveui == "%s") |> filter(fn: (r) => r._field == "t" or r._field == "h" or r._field == "w" or r._field == "p" or r._field == "vp") - |> last() |> yield(name: "last")`,deveui)) + |> last() |> yield(name: "last")`, deveui)) - req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) - if err != nil { - log.Fatal("Error reading request. ", err) - } - - // Set headers - req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==") - req.Header.Set("accept", "application/csv") - req.Header.Set("content-type", "application/vnd.flux") + req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) + if err != nil { + log.Fatal("Error reading request. ", err) + } - // Set client timeout - client := &http.Client{Timeout: time.Second * 10} + // Set headers + req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==") + req.Header.Set("accept", "application/csv") + req.Header.Set("content-type", "application/vnd.flux") - // Send request - resp, err := client.Do(req) - if err != nil { - log.Fatal("Error reading response. ", err) - } - defer resp.Body.Close() + // Set client timeout + client := &http.Client{Timeout: time.Second * 10} - fmt.Println("response Status:", resp.Status) - fmt.Println("response Headers:", resp.Header) + // Send request + resp, err := client.Do(req) + if err != nil { + log.Fatal("Error reading response. ", err) + } + defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Fatal("Error reading body. ", err) - } - fmt.Println("response Body:", string(body)) - - scanner := bufio.NewScanner(strings.NewReader(string(body))) - location, err := time.LoadLocation("Europe/Zurich") - for scanner.Scan() { - s := strings.Split(scanner.Text(),",") - if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) { - mytime,err := time.Parse(time.RFC3339,s[5]) - if err != nil { - continue - } - res.Timestamp = mytime.In(location).Format("02.01.2006 15:04") - value := s[6] - field := s[7] - if field == "t" { - res.Temperature = value - } else if field == "h" { - res.Humidity = value - } else if field == "w" { - res.Weight = value - i, err := strconv.Atoi(value) - if (err == nil) { - res.Weight_kg = fmt.Sprintf("%.2f",float64(i) / 1000.0) - } else { - res.Weight_kg = "ERR" - } - } else if field == "p" { - res.Pressure = value - } else if field == "vp" { - res.BatteryPercent = value - } - } - } - res.Deveui = deveui - res.Alias = getDevAlias(deveui) - res.Alarmactive = getDevAlarmactive(deveui) - res.Smsnumber = getDevSmsnumber(deveui) - res.ActiveUntil = getActiveUntil(deveui) - res.DaysUntilDeactivated = CalcDaysUntil(res.ActiveUntil) - return res + fmt.Println("response Status:", resp.Status) + fmt.Println("response Headers:", resp.Header) + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatal("Error reading body. ", err) + } + fmt.Println("response Body:", string(body)) + + scanner := bufio.NewScanner(strings.NewReader(string(body))) + location, err := time.LoadLocation("Europe/Zurich") + for scanner.Scan() { + s := strings.Split(scanner.Text(), ",") + if (len(s) >= 7) && !(strings.HasPrefix(s[5], "_")) { + mytime, err := time.Parse(time.RFC3339, s[5]) + if err != nil { + continue + } + res.Timestamp = mytime.In(location).Format("02.01.2006 15:04") + value := s[6] + field := s[7] + if field == "t" { + res.Temperature = value + } else if field == "h" { + res.Humidity = value + } else if field == "w" { + res.Weight = value + i, err := strconv.Atoi(value) + if err == nil { + res.Weight_kg = fmt.Sprintf("%.2f", float64(i)/1000.0) + } else { + res.Weight_kg = "ERR" + } + } else if field == "p" { + res.Pressure = value + } else if field == "vp" { + res.BatteryPercent = value + } + } + } + res.Deveui = deveui + res.Alias = getDevAlias(deveui) + res.Alarmactive = getDevAlarmactive(deveui) + res.Smsnumber = getDevSmsnumber(deveui) + res.ActiveUntil = getActiveUntil(deveui) + res.DaysUntilDeactivated = CalcDaysUntil(res.ActiveUntil) + return res } diff --git a/persistence.go b/persistence.go index 5245f5a..8f9247a 100644 --- a/persistence.go +++ b/persistence.go @@ -1,13 +1,13 @@ package main import ( - "time" - "strings" - "fmt" - "log" "crypto/rand" + "fmt" + "github.com/gomodule/redigo/redis" "golang.org/x/crypto/bcrypt" - "github.com/gomodule/redigo/redis" + "log" + "strings" + "time" ) var globalPool *redis.Pool @@ -44,18 +44,18 @@ func ping(c redis.Conn) error { return err } - logit("PING Response = "+s) + logit("PING Response = " + s) // Output: PONG return nil } type Dev struct { - Deveui string - Alias string - Alarmactive string - Smsnumber string - ActiveUntil string // Abo bezahlt bis TT.MM.YYYY + Deveui string + Alias string + Alarmactive string + Smsnumber string + ActiveUntil string // Abo bezahlt bis TT.MM.YYYY } func initDB() { @@ -64,17 +64,17 @@ func initDB() { pool := newPool() // get a connection from the globalPool (redis.Conn) conn := pool.Get() - defer conn.Close() + defer conn.Close() - globalPool = pool + globalPool = pool - // wir machen einen Connection Test - ping(conn) + // wir machen einen Connection Test + ping(conn) - // Wir legen einen initialen Admin User an, falls es diesen noch nicht gibt - if checkUserAvailable("joerg.lehmann@nbit.ch") { - insertUser("joerg.lehmann@nbit.ch","changeme123","Y"); - } + // Wir legen einen initialen Admin User an, falls es diesen noch nicht gibt + if checkUserAvailable("joerg.lehmann@nbit.ch") { + insertUser("joerg.lehmann@nbit.ch", "changeme123", "Y") + } } @@ -82,10 +82,9 @@ func closeDB() { globalPool.Close() } - func updateScaleSettings(scaleSettings Dev) error { - conn := globalPool.Get() - defer conn.Close() + conn := globalPool.Get() + defer conn.Close() // SET object _, err := conn.Do("HMSET", devPrefix+scaleSettings.Deveui, "alias", scaleSettings.Alias, "alarmactive", scaleSettings.Alarmactive, "smsnumber", scaleSettings.Smsnumber) @@ -96,301 +95,294 @@ func updateScaleSettings(scaleSettings Dev) error { return nil } - func checkUserAvailable(username string) bool { - logit("checkUserAvailable: User: "+username) - conn := globalPool.Get() - defer conn.Close() + logit("checkUserAvailable: User: " + username) + conn := globalPool.Get() + defer conn.Close() - _, err := redis.String(conn.Do("GET", userPrefix+username)) - if (err == redis.ErrNil) { - logit("User does not exist and is therefore available:"+username) - return true - } else if err != nil { - logit("checkUserAvailable: Error to query Key Value Store") - return false + _, err := redis.String(conn.Do("GET", userPrefix+username)) + if err == redis.ErrNil { + logit("User does not exist and is therefore available:" + username) + return true + } else if err != nil { + logit("checkUserAvailable: Error to query Key Value Store") + return false } return false } func getMyDevs(username string) []string { - res := []string{} + res := []string{} - if username == "" { - return res - } + if username == "" { + return res + } + conn := globalPool.Get() + defer conn.Close() - conn := globalPool.Get() - defer conn.Close() - - logit("getMyDevs: User: "+username) + logit("getMyDevs: User: " + username) mydevs, err := redis.String(conn.Do("HGET", userPrefix+username, "my_devs")) - if err == nil { - logit("getMyDevs: mydevs: "+mydevs) - res = strings.Split(mydevs, ",") - } else { - log.Print(err) - } + if err == nil { + logit("getMyDevs: mydevs: " + mydevs) + res = strings.Split(mydevs, ",") + } else { + log.Print(err) + } - return res + return res } func getDevAlias(deveui string) string { - res := deveui + res := deveui - if deveui == "" { - return res - } + if deveui == "" { + return res + } + conn := globalPool.Get() + defer conn.Close() - conn := globalPool.Get() - defer conn.Close() - - logit("getDevAlias: Deveui: "+deveui) + logit("getDevAlias: Deveui: " + deveui) alias, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alias")) - if err == nil { - logit("getDevAlias: alias: "+alias) - res = alias - } else { - log.Print(err) - } + if err == nil { + logit("getDevAlias: alias: " + alias) + res = alias + } else { + log.Print(err) + } - return res + return res } func getDevAlarmactive(deveui string) string { - res := "0" + res := "0" - if deveui == "" { - return res - } + if deveui == "" { + return res + } + conn := globalPool.Get() + defer conn.Close() - conn := globalPool.Get() - defer conn.Close() - - logit("getDevAlarmactive: Deveui: "+deveui) + logit("getDevAlarmactive: Deveui: " + deveui) alarmactive, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alarmactive")) - if err == nil { - logit("getDevAlarmactive: alarmactive: "+alarmactive) - res = alarmactive - } else { - log.Print(err) - } + if err == nil { + logit("getDevAlarmactive: alarmactive: " + alarmactive) + res = alarmactive + } else { + log.Print(err) + } - return res + return res } func getDevSmsnumber(deveui string) string { - res := "+4179XXXXXXX" + res := "+4179XXXXXXX" - if deveui == "" { - return res - } + if deveui == "" { + return res + } + conn := globalPool.Get() + defer conn.Close() - conn := globalPool.Get() - defer conn.Close() - - logit("getDevSmsnumber: Deveui: "+deveui) + logit("getDevSmsnumber: Deveui: " + deveui) smsnumber, err := redis.String(conn.Do("HGET", devPrefix+deveui, "smsnumber")) - if err == nil { - logit("getDevAlarmactive: smsnumber: "+smsnumber) - res = smsnumber - } else { - log.Print(err) - } + if err == nil { + logit("getDevAlarmactive: smsnumber: " + smsnumber) + res = smsnumber + } else { + log.Print(err) + } - return res + return res } func getActiveUntil(deveui string) string { - res := "" + res := "" - if deveui == "" { - return res - } + if deveui == "" { + return res + } + conn := globalPool.Get() + defer conn.Close() - conn := globalPool.Get() - defer conn.Close() - - logit("getActiveUntil: Deveui: "+deveui) + logit("getActiveUntil: Deveui: " + deveui) activeuntil, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until")) - if err == nil { - logit("getActiveUntil: activeuntil: "+activeuntil) - res = activeuntil - } else { - log.Print(err) - } + if err == nil { + logit("getActiveUntil: activeuntil: " + activeuntil) + res = activeuntil + } else { + log.Print(err) + } - return res + return res } func AboExpired(deveui string) bool { - active_until := getActiveUntil(deveui); - - layout := "02.01.2006" - t, _ := time.Parse(layout, active_until) + active_until := getActiveUntil(deveui) - return t.Before(time.Now()) + layout := "02.01.2006" + t, _ := time.Parse(layout, active_until) + + return t.Before(time.Now()) } func prolongActivation(deveui string, years int) (string, error) { - conn := globalPool.Get() - defer conn.Close() + conn := globalPool.Get() + defer conn.Close() active_until_old, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until")) - if err == nil { - logit("prolongActivation: active_until: " +active_until_old) - } else { - log.Print(err) - } + if err == nil { + logit("prolongActivation: active_until: " + active_until_old) + } else { + log.Print(err) + } - layout := "02.01.2006" - t, err := time.Parse(layout, active_until_old) + layout := "02.01.2006" + t, err := time.Parse(layout, active_until_old) - if err != nil { - fmt.Println(err) - } - fmt.Println(t.Unix()) + if err != nil { + fmt.Println(err) + } + fmt.Println(t.Unix()) - var t_new time.Time - if t.Before(time.Now()) { - t_new = time.Now().AddDate(years, 0, 0) - } else { - t_new = t.AddDate(years, 0, 0) - } - active_until_new := t_new.Format(layout) + var t_new time.Time + if t.Before(time.Now()) { + t_new = time.Now().AddDate(years, 0, 0) + } else { + t_new = t.AddDate(years, 0, 0) + } + active_until_new := t_new.Format(layout) // SET object _, err1 := conn.Do("HMSET", devPrefix+deveui, "active_until", active_until_new) if err1 != nil { - return "",err1 + return "", err1 } return active_until_new, nil } func randString(n int) string { - const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - var bytes = make([]byte, n) - rand.Read(bytes) - for i, b := range bytes { - bytes[i] = alphanum[b % byte(len(alphanum))] - } - return string(bytes) + const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + var bytes = make([]byte, n) + rand.Read(bytes) + for i, b := range bytes { + bytes[i] = alphanum[b%byte(len(alphanum))] + } + return string(bytes) } -func insertUser(username,password,is_admin string) { - conn := globalPool.Get() - defer conn.Close() - logit("insertUser: "+username) - pwd := []byte(password) - hashedPassword,err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost) +func insertUser(username, password, is_admin string) { + conn := globalPool.Get() + defer conn.Close() + logit("insertUser: " + username) + pwd := []byte(password) + hashedPassword, err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost) if err != nil { - logit("insertUser: Error with bcrypt.GenerateFromPassword, User: "+username) + logit("insertUser: Error with bcrypt.GenerateFromPassword, User: " + username) return } - confirm_id := "" + confirm_id := "" - _, err = conn.Do("HMSET", userPrefix+username, "password", string(hashedPassword), "new_password", string(hashedPassword), "confirm_id", confirm_id, "last_login", "", "my_devs","") + _, err = conn.Do("HMSET", userPrefix+username, "password", string(hashedPassword), "new_password", string(hashedPassword), "confirm_id", confirm_id, "last_login", "", "my_devs", "") if err != nil { - logit("insertUser: Error inserting User: "+username) + logit("insertUser: Error inserting User: " + username) return - } + } } -func updateUser(username,password string) { - conn := globalPool.Get() - defer conn.Close() - logit("updateUser: "+username) - pwd := []byte(password) - hashedPassword,err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost) +func updateUser(username, password string) { + conn := globalPool.Get() + defer conn.Close() + logit("updateUser: " + username) + pwd := []byte(password) + hashedPassword, err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost) if err != nil { - logit("updateUser: Error with bcrypt.GenerateFromPassword, User: "+username) + logit("updateUser: Error with bcrypt.GenerateFromPassword, User: " + username) return } confirm_id := randString(30) _, err = conn.Do("HMSET", userPrefix+username, "new_password", string(hashedPassword), "confirm_id", confirm_id) if err != nil { - logit("updateUser: Error updateing User: "+username) - return - } - _, err = conn.Do("SET", confirmPrefix+confirm_id,username) + logit("updateUser: Error updateing User: " + username) + return + } + _, err = conn.Do("SET", confirmPrefix+confirm_id, username) if err != nil { - logit("updateUser: Error inserting confirm_id: "+confirm_id+": "+username) - return - } + logit("updateUser: Error inserting confirm_id: " + confirm_id + ": " + username) + return + } - sendEmail(username,confirm_id) + sendEmail(username, confirm_id) } -func checkLoginCredentials(username,password string) bool { - conn := globalPool.Get() - defer conn.Close() +func checkLoginCredentials(username, password string) bool { + conn := globalPool.Get() + defer conn.Close() - logit("checkLoginCredentials: called with username,password: "+username+","+password) + logit("checkLoginCredentials: called with username,password: " + username + "," + password) pwd, err := redis.String(conn.Do("HGET", userPrefix+username, "password")) - if err == nil { - logit("checkLoginCredentials: pwd: "+pwd+" CMD: HGET "+userPrefix+username+userPrefix+username+" confirm_id") - cid, err := redis.String(conn.Do("HGET", userPrefix+username, "confirm_id")) - if err == nil { - logit("checkLoginCredentials: cid: "+cid) - if !(err != nil && cid != "") { - logit("checkLoginCredentials: pwd: "+pwd) - if err != nil { - return false - } - } - } - } else { - log.Print(err) - return false - } + if err == nil { + logit("checkLoginCredentials: pwd: " + pwd + " CMD: HGET " + userPrefix + username + userPrefix + username + " confirm_id") + cid, err := redis.String(conn.Do("HGET", userPrefix+username, "confirm_id")) + if err == nil { + logit("checkLoginCredentials: cid: " + cid) + if !(err != nil && cid != "") { + logit("checkLoginCredentials: pwd: " + pwd) + if err != nil { + return false + } + } + } + } else { + log.Print(err) + return false + } - hashedPassword := []byte(pwd) + hashedPassword := []byte(pwd) err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password)) return err == nil } func updateLoginTime(username string) { - conn := globalPool.Get() - defer conn.Close() + conn := globalPool.Get() + defer conn.Close() _, err := conn.Do("HSET", userPrefix+username, "last_login", time.Now().UTC().Format("2006-01-02 15:04:05")) if err != nil { - logit("updateUser: Error updateing User: "+username) - return - } + logit("updateUser: Error updateing User: " + username) + return + } } func confirmUser(confirm_id string) { - conn := globalPool.Get() - defer conn.Close() + conn := globalPool.Get() + defer conn.Close() u, err := redis.String(conn.Do("GET", confirmPrefix+confirm_id)) - if err != nil { - logit("confirmUser: Error with searching confirm_id: "+confirm_id) - return - } + if err != nil { + logit("confirmUser: Error with searching confirm_id: " + confirm_id) + return + } new_password, err := redis.String(conn.Do("HGET", userPrefix+u, "new_password")) - if err != nil { - logit("confirmUser: Error with getting new_password: "+u) - return - } + if err != nil { + logit("confirmUser: Error with getting new_password: " + u) + return + } _, err = conn.Do("HMSET", userPrefix+u, "confirm_id", "", "password", new_password) if err != nil { - logit("confirmUser: Error updateing User: "+u) - return - } + logit("confirmUser: Error updateing User: " + u) + return + } _, err = conn.Do("DEL", confirmPrefix+confirm_id) if err != nil { - logit("confirmUser: Error deleting confirm_id: "+confirm_id) - return - } + logit("confirmUser: Error deleting confirm_id: " + confirm_id) + return + } } - diff --git a/scales.go b/scales.go index 6bc1d34..3cb4584 100644 --- a/scales.go +++ b/scales.go @@ -1,109 +1,109 @@ package main import ( - "fmt" - "log" - "regexp" - "net/http" + "fmt" + "log" + "net/http" + "regexp" ) // scales handler func save_scale_settingsHandler(response http.ResponseWriter, request *http.Request) { - name := getUserName(request) - if name != "" { + name := getUserName(request) + if name != "" { - deveui, ok := request.URL.Query()["deveui"] + deveui, ok := request.URL.Query()["deveui"] - if !ok || len(deveui[0]) < 1 { - log.Println("Url Param 'deveui' is missing") - fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"deveui must be specified in URL\" }") - return - } - // Query()["deveui"] will return an array of items, - // we only want the single item. - mydeveui := deveui[0] - - if (len(mydeveui) != 16) { - log.Println("specified 'deveui' has invalid length") - fmt.Fprintf(response, "{ \"rc\": 8, \"msg\": \"specified deveui has invalid length\" }") - return - } - - if !(Contains(getMyDevs(name),mydeveui)) { - log.Println("specified 'deveui' does not belong to this user") - fmt.Fprintf(response, "{ \"rc\": 2, \"msg\": \"specified deveui does not belong to this user\" }") - return - } + if !ok || len(deveui[0]) < 1 { + log.Println("Url Param 'deveui' is missing") + fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"deveui must be specified in URL\" }") + return + } + // Query()["deveui"] will return an array of items, + // we only want the single item. + mydeveui := deveui[0] - log.Println("Url Param 'deveui' is: " + string(mydeveui)) + if len(mydeveui) != 16 { + log.Println("specified 'deveui' has invalid length") + fmt.Fprintf(response, "{ \"rc\": 8, \"msg\": \"specified deveui has invalid length\" }") + return + } - alias, ok2 := request.URL.Query()["alias"] + if !(Contains(getMyDevs(name), mydeveui)) { + log.Println("specified 'deveui' does not belong to this user") + fmt.Fprintf(response, "{ \"rc\": 2, \"msg\": \"specified deveui does not belong to this user\" }") + return + } - if !ok2 || len(alias[0]) < 1 { - log.Println("Url Param 'alias' is missing") - fmt.Fprintf(response, "{ \"rc\": 3, \"msg\": \"alias must be specified in URL\" }") - return - } - myalias := alias[0] + log.Println("Url Param 'deveui' is: " + string(mydeveui)) - // validate alias - match, _ := regexp.MatchString("^[a-zA-Z0-9 ]{1,16}$", myalias) - if !(match) { - log.Println("Url Param 'alias' is not valid") - fmt.Fprintf(response, "{ \"rc\": 9, \"msg\": \"alias is not valid\" }") - return - } - - alarmactive, ok3 := request.URL.Query()["alarmactive"] + alias, ok2 := request.URL.Query()["alias"] - if !ok3 || len(alarmactive[0]) < 1 { - log.Println("Url Param 'alarmactive' is missing") - fmt.Fprintf(response, "{ \"rc\": 4, \"msg\": \"alarmactive must be specified in URL\" }") - return - } - myalarmactive := alarmactive[0] + if !ok2 || len(alias[0]) < 1 { + log.Println("Url Param 'alias' is missing") + fmt.Fprintf(response, "{ \"rc\": 3, \"msg\": \"alias must be specified in URL\" }") + return + } + myalias := alias[0] - if !((myalarmactive == "0") || (myalarmactive == "1")) { - log.Println("Url Param 'alarmactive' is not valid") - fmt.Fprintf(response, "{ \"rc\": 10, \"msg\": \"alarmactive is not valid\" }") - return - } - - smsnumber, ok4 := request.URL.Query()["smsnumber"] + // validate alias + match, _ := regexp.MatchString("^[a-zA-Z0-9 ]{1,16}$", myalias) + if !(match) { + log.Println("Url Param 'alias' is not valid") + fmt.Fprintf(response, "{ \"rc\": 9, \"msg\": \"alias is not valid\" }") + return + } - if !ok4 || len(smsnumber[0]) < 1 { - log.Println("Url Param 'smsnumber' is missing") - fmt.Fprintf(response, "{ \"rc\": 5, \"msg\": \"smsnumber must be specified in URL\" }") - return - } - mysmsnumber := smsnumber[0] + alarmactive, ok3 := request.URL.Query()["alarmactive"] - match1, _ := regexp.MatchString(`^\+[0-9]{11,11}$`, mysmsnumber) - if !(match1) { - log.Println("Url Param 'smsnumber' is not valid") - fmt.Fprintf(response, "{ \"rc\": 11, \"msg\": \"smsnumber is not valid, must be in in format +41791234567\" }") - return - } + if !ok3 || len(alarmactive[0]) < 1 { + log.Println("Url Param 'alarmactive' is missing") + fmt.Fprintf(response, "{ \"rc\": 4, \"msg\": \"alarmactive must be specified in URL\" }") + return + } + myalarmactive := alarmactive[0] - var mydev Dev - mydev.Deveui = mydeveui - mydev.Alias = myalias - mydev.Alarmactive = myalarmactive - mydev.Smsnumber = mysmsnumber + if !((myalarmactive == "0") || (myalarmactive == "1")) { + log.Println("Url Param 'alarmactive' is not valid") + fmt.Fprintf(response, "{ \"rc\": 10, \"msg\": \"alarmactive is not valid\" }") + return + } - // now we try to save the settings - err := updateScaleSettings(mydev) - - if err != nil { - log.Println("Error to Update Device Settings") - fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"error with saving device settings\" }") - return - } else { - fmt.Fprintf(response, "{ \"rc\": 0, \"msg\": \"SUCCESS\" }") - } - - } else { - fmt.Fprintf(response, "{ \"rc\": 7, \"msg\": \"Only available for logged in users\" }") - } + smsnumber, ok4 := request.URL.Query()["smsnumber"] + + if !ok4 || len(smsnumber[0]) < 1 { + log.Println("Url Param 'smsnumber' is missing") + fmt.Fprintf(response, "{ \"rc\": 5, \"msg\": \"smsnumber must be specified in URL\" }") + return + } + mysmsnumber := smsnumber[0] + + match1, _ := regexp.MatchString(`^\+[0-9]{11,11}$`, mysmsnumber) + if !(match1) { + log.Println("Url Param 'smsnumber' is not valid") + fmt.Fprintf(response, "{ \"rc\": 11, \"msg\": \"smsnumber is not valid, must be in in format +41791234567\" }") + return + } + + var mydev Dev + mydev.Deveui = mydeveui + mydev.Alias = myalias + mydev.Alarmactive = myalarmactive + mydev.Smsnumber = mysmsnumber + + // now we try to save the settings + err := updateScaleSettings(mydev) + + if err != nil { + log.Println("Error to Update Device Settings") + fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"error with saving device settings\" }") + return + } else { + fmt.Fprintf(response, "{ \"rc\": 0, \"msg\": \"SUCCESS\" }") + } + + } else { + fmt.Fprintf(response, "{ \"rc\": 7, \"msg\": \"Only available for logged in users\" }") + } } diff --git a/stripe.go b/stripe.go index 3faca83..674fe73 100644 --- a/stripe.go +++ b/stripe.go @@ -1,119 +1,125 @@ package main import ( - "fmt" - "log" - "os" - "io/ioutil" - "encoding/json" - "net/http" - "strings" - "strconv" - "github.com/stripe/stripe-go" - "github.com/stripe/stripe-go/paymentintent" + "encoding/json" + "fmt" + "github.com/stripe/stripe-go" + "github.com/stripe/stripe-go/paymentintent" + "io/ioutil" + "log" + "net/http" + "os" + "strconv" + "strings" ) func getStripeKey() string { - return "sk_test_GJbXPD0IAFNvvGpNEpaeDfhl" + return "sk_test_GJbXPD0IAFNvvGpNEpaeDfhl" } func getstripepaymentintentHandler(response http.ResponseWriter, request *http.Request) { - name := getUserName(request) - if name != "" { + name := getUserName(request) + if name != "" { - charge_data, ok := request.URL.Query()["charge_data"] - if !ok || len(charge_data[0]) < 1 { - log.Println("Url Param 'charge_data' is missing") - fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"charge_data must be specified in URL\" }") - return - } + charge_data, ok := request.URL.Query()["charge_data"] + if !ok || len(charge_data[0]) < 1 { + log.Println("Url Param 'charge_data' is missing") + fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"charge_data must be specified in URL\" }") + return + } - scales := strings.Split(charge_data[0],",") + scales := strings.Split(charge_data[0], ",") - var abo_years = 0 - var items []string - for _,scale := range scales { - items = strings.Split(scale,":") - if (len(items) == 2) { - abo_count, err := strconv.Atoi(items[1]) - if err == nil { - abo_years += abo_count - } - } - } - abo_amount := int64(abo_years * 2400) + var abo_years = 0 + var items []string + for _, scale := range scales { + items = strings.Split(scale, ":") + if len(items) == 2 { + abo_count, err := strconv.Atoi(items[1]) + if err == nil { + abo_years += abo_count + } + } + } + abo_amount := int64(abo_years * 2400) - stripe.Key = getStripeKey() + stripe.Key = getStripeKey() - params := &stripe.PaymentIntentParams{ - Amount: stripe.Int64(abo_amount), - Currency: stripe.String(string(stripe.CurrencyCHF)), - ReceiptEmail: stripe.String(name), - } - params.AddMetadata("charge_data", charge_data[0]) - paymentintent, err := paymentintent.New(params) - - if err != nil { - fmt.Fprintf(response,"{ \"rc\": 5, \"stripeclientsecret\": \"%s\" }\n",err) - } else { - fmt.Fprintf(response,"{ \"rc\": 0, \"stripeclientsecret\": \"%s\" }\n",paymentintent.ClientSecret) - } + params := &stripe.PaymentIntentParams{ + Amount: stripe.Int64(abo_amount), + Currency: stripe.String(string(stripe.CurrencyCHF)), + ReceiptEmail: stripe.String(name), + } + params.AddMetadata("charge_data", charge_data[0]) + paymentintent, err := paymentintent.New(params) - } else { - fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"Only available for logged in users\" }") - } + if err != nil { + fmt.Fprintf(response, "{ \"rc\": 5, \"stripeclientsecret\": \"%s\" }\n", err) + } else { + fmt.Fprintf(response, "{ \"rc\": 0, \"stripeclientsecret\": \"%s\" }\n", paymentintent.ClientSecret) + } + + } else { + fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"Only available for logged in users\" }") + } } func HandlePayment(user string, charge_data string, amount int64) { - fmt.Printf("HandlePayment for %s (charge_data: %s, amount: %d)!\n", user, charge_data, amount) - for _, token := range strings.Split(charge_data,",") { - res := strings.Split(token,":") - if (len(res)) == 2 { - deveui := res[0] - years, _ := strconv.Atoi(res[1]) - fmt.Printf("prolongActivation %s: %d\n", deveui, years) - prolongActivation(deveui, years) - } - } - sendPaymentConfirmationEmail(user,charge_data,amount) + fmt.Printf("HandlePayment for %s (charge_data: %s, amount: %d)!\n", user, charge_data, amount) + charge_data_email_text := fmt.Sprintf("%-30s %20s %10s\n", "Alias", "verlängern bis", "Betrag") + charge_data_email_text = charge_data_email_text + strings.Repeat("-", 62) + "\n" + for _, token := range strings.Split(charge_data, ",") { + res := strings.Split(token, ":") + if (len(res)) == 2 { + deveui := res[0] + years, _ := strconv.Atoi(res[1]) + fmt.Printf("prolongActivation %s: %d\n", deveui, years) + prolongActivation(deveui, years) + line := fmt.Sprintf("%-30s %20s %10.2f\n", getDevAlias(deveui), getActiveUntil(deveui), float64(24*years)) + charge_data_email_text = charge_data_email_text + line + } + } + charge_data_email_text = charge_data_email_text + strings.Repeat("-", 62) + "\n" + charge_data_email_text = charge_data_email_text + fmt.Sprintf("%-30s %20s %10.2f\n", "Total CHF", "", float64(amount/100)) + sendPaymentConfirmationEmail(user, charge_data_email_text, amount) } func stripeWebhookHandler(w http.ResponseWriter, req *http.Request) { - const MaxBodyBytes = int64(65536) - req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes) - payload, err := ioutil.ReadAll(req.Body) - if err != nil { - fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err) - w.WriteHeader(http.StatusServiceUnavailable) - return - } + const MaxBodyBytes = int64(65536) + req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes) + payload, err := ioutil.ReadAll(req.Body) + if err != nil { + fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err) + w.WriteHeader(http.StatusServiceUnavailable) + return + } - event := stripe.Event{} + event := stripe.Event{} - if err := json.Unmarshal(payload, &event); err != nil { - fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error()) - w.WriteHeader(http.StatusBadRequest) - return - } + if err := json.Unmarshal(payload, &event); err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error()) + w.WriteHeader(http.StatusBadRequest) + return + } - // Unmarshal the event data into an appropriate struct depending on its Type - switch event.Type { - case "payment_intent.succeeded": - var paymentIntent stripe.PaymentIntent - err := json.Unmarshal(event.Data.Raw, &paymentIntent) - if err != nil { - fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) - w.WriteHeader(http.StatusBadRequest) - return - } - fmt.Printf("PaymentIntent was successful (charge_data: %s, amount: %d)!\n", paymentIntent.Metadata["charge_data"], paymentIntent.Amount) - HandlePayment(paymentIntent.ReceiptEmail, paymentIntent.Metadata["charge_data"], paymentIntent.Amount) - // ... handle other event types - default: - fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type) - w.WriteHeader(http.StatusBadRequest) - return - } + // Unmarshal the event data into an appropriate struct depending on its Type + switch event.Type { + case "payment_intent.succeeded": + var paymentIntent stripe.PaymentIntent + err := json.Unmarshal(event.Data.Raw, &paymentIntent) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) + w.WriteHeader(http.StatusBadRequest) + return + } + fmt.Printf("PaymentIntent was successful (charge_data: %s, amount: %d)!\n", paymentIntent.Metadata["charge_data"], paymentIntent.Amount) + HandlePayment(paymentIntent.ReceiptEmail, paymentIntent.Metadata["charge_data"], paymentIntent.Amount) + // ... handle other event types + default: + fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type) + w.WriteHeader(http.StatusBadRequest) + return + } - w.WriteHeader(http.StatusOK) + w.WriteHeader(http.StatusOK) }