go fmt; email message after payment

This commit is contained in:
Joerg Lehmann 2020-04-09 14:41:41 +02:00
parent 2cac4d56e2
commit 5548949e9d
9 changed files with 791 additions and 795 deletions

View File

@ -1,11 +1,11 @@
package main package main
import ( import (
"crypto/md5"
"encoding/hex"
"fmt"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"net/http" "net/http"
"fmt"
"crypto/md5"
"encoding/hex"
) )
// cookie handling // cookie handling
@ -31,9 +31,9 @@ func getUserNameHash(request *http.Request) (userName string) {
userName = cookieValue["name"] userName = cookieValue["name"]
} }
} }
hasher := md5.New() hasher := md5.New()
hasher.Write([]byte(userName)) hasher.Write([]byte(userName))
return hex.EncodeToString(hasher.Sum(nil)) return hex.EncodeToString(hasher.Sum(nil))
} }
func setSession(userName string, response http.ResponseWriter) { func setSession(userName string, response http.ResponseWriter) {
@ -67,34 +67,33 @@ func loginHandler(response http.ResponseWriter, request *http.Request) {
pass := request.FormValue("password") pass := request.FormValue("password")
redirectTarget := "/invalid_login.html" redirectTarget := "/invalid_login.html"
// .. check credentials .. // .. check credentials ..
if checkLoginCredentials(name,pass) { if checkLoginCredentials(name, pass) {
redirectTarget = "/scales.html" 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) setSession(name, response)
updateLoginTime(name) updateLoginTime(name)
} else { } 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) http.Redirect(response, request, redirectTarget, 302)
} }
// resetPassword handler // resetPassword handler
func resetPasswordHandler(response http.ResponseWriter, request *http.Request) { func resetPasswordHandler(response http.ResponseWriter, request *http.Request) {
name := request.FormValue("email") name := request.FormValue("email")
pass := request.FormValue("password") pass := request.FormValue("password")
redirectTarget := "/" redirectTarget := "/"
logit(fmt.Sprintf("resetPasswordHandler: request for User %s",name)) logit(fmt.Sprintf("resetPasswordHandler: request for User %s", name))
if name != "" && pass != "" { if name != "" && pass != "" {
if checkUserAvailable(name) { if checkUserAvailable(name) {
http.Redirect(response, request, "/user_does_not_exist.html", 302) http.Redirect(response, request, "/user_does_not_exist.html", 302)
} else { } else {
updateUser(name,pass) updateUser(name, pass)
http.Redirect(response, request, redirectTarget, 302) 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 // setPassword handler
@ -104,10 +103,10 @@ func setPasswordHandler(response http.ResponseWriter, request *http.Request) {
pass := request.FormValue("password") pass := request.FormValue("password")
if name != "" && pass != "" { if name != "" && pass != "" {
if checkUserAvailable(name) { if checkUserAvailable(name) {
http.Redirect(response, request, "/user_does_not_exist.html", 302) http.Redirect(response, request, "/user_does_not_exist.html", 302)
} else { } 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) { func confirmHandler(response http.ResponseWriter, request *http.Request) {
confirm_id := request.URL.Query().Get("id") 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) confirmUser(confirm_id)
http.Redirect(response, request, "/", 302) http.Redirect(response, request, "/", 302)
} }

View File

@ -1,17 +1,17 @@
package main package main
import ( import (
"log" "log"
) )
// Contains tells whether a contains x. // Contains tells whether a contains x.
func Contains(a []string, x string) bool { func Contains(a []string, x string) bool {
log.Println("Search for: "+x) log.Println("Search for: " + x)
for _, n := range a { for _, n := range a {
log.Println("Piece of Array: "+n) log.Println("Piece of Array: " + n)
if x == n { if x == n {
return true return true
} }
} }
return false return false
} }

2
log.go
View File

@ -5,5 +5,5 @@ import (
) )
func logit(log_message string) { func logit(log_message string) {
log.Println(log_message) log.Println(log_message)
} }

82
mail.go
View File

@ -1,26 +1,26 @@
package main package main
import ( import (
"log"
"bytes" "bytes"
"log"
"net/smtp" "net/smtp"
) )
func sendEmail(username,confirm_id string) { func sendEmail(username, confirm_id string) {
c, err := smtp.Dial("127.0.0.1:25") c, err := smtp.Dial("127.0.0.1:25")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer c.Close() defer c.Close()
// Set the sender and recipient. // Set the sender and recipient.
c.Mail("register@mini-beieli.ch") c.Mail("register@mini-beieli.ch")
c.Rcpt(username) c.Rcpt(username)
// Send the email body. // Send the email body.
wc, err := c.Data() wc, err := c.Data()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer wc.Close() defer wc.Close()
mail_message := "To: " + username + ` mail_message := "To: " + username + `
Subject: Passwortaenderung auf https://mini-beieli.ch, bitte bestaetigen Subject: Passwortaenderung auf https://mini-beieli.ch, bitte bestaetigen
@ -37,27 +37,27 @@ Mit freundlichen Grüssen
-- --
mini-beieli.ch` mini-beieli.ch`
buf := bytes.NewBufferString(mail_message) buf := bytes.NewBufferString(mail_message)
if _, err = buf.WriteTo(wc); err != nil { if _, err = buf.WriteTo(wc); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }
func sendPaymentConfirmationEmail(username,charge_data string, amount int64) { func sendPaymentConfirmationEmail(username, charge_data string, amount int64) {
c, err := smtp.Dial("127.0.0.1:25") c, err := smtp.Dial("127.0.0.1:25")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer c.Close() defer c.Close()
// Set the sender and recipient. // Set the sender and recipient.
c.Mail("info@mini-beieli.ch") c.Mail("info@mini-beieli.ch")
c.Rcpt(username) c.Rcpt(username)
// Send the email body. // Send the email body.
wc, err := c.Data() wc, err := c.Data()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer wc.Close() defer wc.Close()
mail_message := "To: " + username + ` mail_message := "To: " + username + `
Subject: Zahlungsbestaetigung mini-beieli.ch Subject: Zahlungsbestaetigung mini-beieli.ch
@ -71,8 +71,8 @@ Mit freundlichen Grüssen
-- --
mini-beieli.ch` mini-beieli.ch`
buf := bytes.NewBufferString(mail_message) buf := bytes.NewBufferString(mail_message)
if _, err = buf.WriteTo(wc); err != nil { if _, err = buf.WriteTo(wc); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

80
main.go
View File

@ -5,11 +5,11 @@ import (
"net/http" "net/http"
"os" "os"
"path" "path"
"time" "time"
) )
func serveTemplate(w http.ResponseWriter, r *http.Request) { 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 // wennn kein File angegeben ist: index.html
if r.URL.Path == "/" { if r.URL.Path == "/" {
r.URL.Path = "/index.html" r.URL.Path = "/index.html"
@ -35,36 +35,36 @@ func serveTemplate(w http.ResponseWriter, r *http.Request) {
return return
} }
var userName = getUserName(r) var userName = getUserName(r)
t := time.Now() t := time.Now()
var datetimestring = t.Format("20060102150405") var datetimestring = t.Format("20060102150405")
var scales = getMyDevs(userName) var scales = getMyDevs(userName)
var last_metrics []OneMetric var last_metrics []OneMetric
query_values := r.URL.Query()
if (r.URL.Path == "/scales.html") { query_values := r.URL.Query()
// wir holen noch die letzten Metriken
for _, v := range scales { if r.URL.Path == "/scales.html" {
last_metric := getLastMetrics(v) // wir holen noch die letzten Metriken
last_metrics = append(last_metrics, last_metric) for _, v := range scales {
} last_metric := getLastMetrics(v)
last_metrics = append(last_metrics, last_metric)
}
} }
data := struct { data := struct {
UserName string UserName string
DateTimeString string DateTimeString string
Scales []string Scales []string
LastMetrics []OneMetric LastMetrics []OneMetric
QueryValues map[string][]string QueryValues map[string][]string
} { }{
userName, userName,
datetimestring, datetimestring,
scales, scales,
last_metrics, last_metrics,
query_values, query_values,
} }
if err := tmpl.ExecuteTemplate(w, "layout", &data); err != nil { if err := tmpl.ExecuteTemplate(w, "layout", &data); err != nil {
logit(err.Error()) logit(err.Error())
@ -73,23 +73,23 @@ func serveTemplate(w http.ResponseWriter, r *http.Request) {
} }
func main() { func main() {
initDB() initDB()
defer closeDB() defer closeDB()
fs := http.FileServer(http.Dir("static")) fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs)) http.Handle("/static/", http.StripPrefix("/static/", fs))
http.Handle("/favicon.ico", fs) http.Handle("/favicon.ico", fs)
http.HandleFunc("/", serveTemplate) http.HandleFunc("/", serveTemplate)
http.HandleFunc("/login", loginHandler) http.HandleFunc("/login", loginHandler)
http.HandleFunc("/reset_password", resetPasswordHandler) http.HandleFunc("/reset_password", resetPasswordHandler)
http.HandleFunc("/set_password", setPasswordHandler) http.HandleFunc("/set_password", setPasswordHandler)
http.HandleFunc("/logout", logoutHandler) http.HandleFunc("/logout", logoutHandler)
http.HandleFunc("/confirm", confirmHandler) http.HandleFunc("/confirm", confirmHandler)
http.HandleFunc("/metrics", metricsHandler) http.HandleFunc("/metrics", metricsHandler)
http.HandleFunc("/lastmetrics", lastmetricsHandler) http.HandleFunc("/lastmetrics", lastmetricsHandler)
http.HandleFunc("/save_scale_settings", save_scale_settingsHandler) http.HandleFunc("/save_scale_settings", save_scale_settingsHandler)
http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler) http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler)
http.HandleFunc("/stripewebhook", stripeWebhookHandler) http.HandleFunc("/stripewebhook", stripeWebhookHandler)
logit("Starting Web Application...") logit("Starting Web Application...")
http.ListenAndServe("127.0.0.1:4000", nil) http.ListenAndServe("127.0.0.1:4000", nil)

View File

@ -1,355 +1,354 @@
package main package main
import ( import (
"bytes" "bufio"
"fmt" "bytes"
"log" "fmt"
"net/http" "io/ioutil"
"time" "log"
"io/ioutil" "net/http"
"bufio" "strconv"
"strings" "strings"
"strconv" "time"
) )
type OneMetric struct { type OneMetric struct {
Deveui string Deveui string
Alias string Alias string
Alarmactive string Alarmactive string
Smsnumber string Smsnumber string
Timestamp string Timestamp string
Temperature string Temperature string
Humidity string Humidity string
Weight string Weight string
Weight_kg string Weight_kg string
Pressure string Pressure string
BatteryPercent string BatteryPercent string
ActiveUntil string ActiveUntil string
DaysUntilDeactivated int // berechneter Wert DaysUntilDeactivated int // berechneter Wert
} }
// metrics handler // metrics handler
func metricsHandler(response http.ResponseWriter, request *http.Request) { func metricsHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request) name := getUserName(request)
if name != "" { if name != "" {
property, ok := request.URL.Query()["property"] property, ok := request.URL.Query()["property"]
if !ok || len(property[0]) < 1 { if !ok || len(property[0]) < 1 {
log.Println("Url Param 'property' is missing") log.Println("Url Param 'property' is missing")
fmt.Fprintf(response, "{ \"msg\": \"property must be specified in URL\" }") fmt.Fprintf(response, "{ \"msg\": \"property must be specified in URL\" }")
return return
} }
deveui, ok := request.URL.Query()["deveui"] deveui, ok := request.URL.Query()["deveui"]
if !ok || len(deveui[0]) < 1 { if !ok || len(deveui[0]) < 1 {
log.Println("Url Param 'deveui' is missing") log.Println("Url Param 'deveui' is missing")
fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }") fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }")
return return
} }
// Query()["deveui"] will return an array of items, // Query()["deveui"] will return an array of items,
// we only want the single item. // we only want the single item.
mydeveui := deveui[0] 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 AboExpired(mydeveui) { if !(Contains(getMyDevs(name), mydeveui)) {
log.Println("specified 'deveui' has an expired abo") log.Println("specified 'deveui' does not belong to this user")
fmt.Fprintf(response, "{ \"msg\": \"specified deveui has an expired abo\" }") fmt.Fprintf(response, "{ \"msg\": \"specified deveui does not belong to this user\" }")
return 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"] // Format of start and stop: YYYY-MM-DDTHH:MI:SSZ
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")
}
if ok { stop, ok := request.URL.Query()["stop"]
mystop = stop[0] 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" if ok {
stopDate, err := time.Parse(layout, mystop) mystop = stop[0]
}
if err != nil { layout := "2006-01-02T15:04:05Z"
fmt.Println(err) stopDate, err := time.Parse(layout, mystop)
}
start, ok := request.URL.Query()["start"] if err != nil {
var mystart string fmt.Println(err)
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 ok { start, ok := request.URL.Query()["start"]
mystart = start[0] 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" if ok {
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)) mystart = start[0]
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) url := "http://localhost:9999/api/v2/query?org=beieliorg"
if err != nil { 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))
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)
body, err := ioutil.ReadAll(resp.Body) req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil { if err != nil {
log.Fatal("Error reading body. ", err) log.Fatal("Error reading request. ", 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 { // Set headers
fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }") 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) { func lastmetricsHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request) name := getUserName(request)
if name != "" { if name != "" {
deveui, ok := request.URL.Query()["deveui"] deveui, ok := request.URL.Query()["deveui"]
if !ok || len(deveui[0]) < 1 { if !ok || len(deveui[0]) < 1 {
log.Println("Url Param 'deveui' is missing") log.Println("Url Param 'deveui' is missing")
fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }") fmt.Fprintf(response, "{ \"msg\": \"deveui must be specified in URL\" }")
return return
} }
// Query()["deveui"] will return an array of items, // Query()["deveui"] will return an array of items,
// we only want the single item. // we only want the single item.
mydeveui := deveui[0] 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
}
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" log.Println("Url Param 'deveui' is: " + string(mydeveui))
//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") 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) |> range(start:-365d)
|> filter(fn: (r) => r.deveui == "%s") |> 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") |> 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)) req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil { if err != nil {
log.Fatal("Error reading request. ", err) 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)
body, err := ioutil.ReadAll(resp.Body) // Set headers
if err != nil { req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==")
log.Fatal("Error reading body. ", err) req.Header.Set("accept", "application/csv")
} req.Header.Set("content-type", "application/vnd.flux")
fmt.Println("response Body:", string(body))
// Set client timeout
scanner := bufio.NewScanner(strings.NewReader(string(body))) client := &http.Client{Timeout: time.Second * 10}
ts := ""
t := "" // Send request
h := "" resp, err := client.Do(req)
w := "" if err != nil {
p := "" log.Fatal("Error reading response. ", err)
vp := "" }
location, err := time.LoadLocation("Europe/Zurich") defer resp.Body.Close()
for scanner.Scan() {
s := strings.Split(scanner.Text(),",") fmt.Println("response Status:", resp.Status)
if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) { fmt.Println("response Headers:", resp.Header)
mytime,err := time.Parse(time.RFC3339,s[5])
if err != nil { body, err := ioutil.ReadAll(resp.Body)
continue if err != nil {
} log.Fatal("Error reading body. ", err)
ts = mytime.In(location).Format("02.01.2006 15:04") }
value := s[6] fmt.Println("response Body:", string(body))
field := s[7]
if field == "t" { scanner := bufio.NewScanner(strings.NewReader(string(body)))
t = value ts := ""
} else if field == "h" { t := ""
h = value h := ""
} else if field == "w" { w := ""
w = value p := ""
} else if field == "p" { vp := ""
p = value location, err := time.LoadLocation("Europe/Zurich")
} else if field == "vp" { for scanner.Scan() {
vp = value s := strings.Split(scanner.Text(), ",")
} if (len(s) >= 7) && !(strings.HasPrefix(s[5], "_")) {
} mytime, err := time.Parse(time.RFC3339, s[5])
} if err != nil {
fmt.Fprintf(response,`{ 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", "ts": "%s",
"t": "%s", "t": "%s",
"h": "%s", "h": "%s",
"w": "%s", "w": "%s",
"p": "%s", "p": "%s",
"vp": "%s" "vp": "%s"
}`,ts,t,h,w,p,vp) }`, ts, t, h, w, p, vp)
} else { } else {
fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }") fmt.Fprintf(response, "{ \"msg\": \"Only available for logged in users\" }")
} }
} }
func CalcDaysUntil(mydate string) int { func CalcDaysUntil(mydate string) int {
var days int var days int
layout := "02.01.2006" layout := "02.01.2006"
t, err := time.Parse(layout, mydate) t, err := time.Parse(layout, mydate)
if err != nil { if err != nil {
days = 0 days = 0
} }
days = int(t.Sub(time.Now()).Hours() / 24) days = int(t.Sub(time.Now()).Hours() / 24)
return days return days
} }
func getLastMetrics(deveui string) OneMetric { func getLastMetrics(deveui string) OneMetric {
var res OneMetric var res OneMetric
url := "http://localhost:9999/api/v2/query?org=beieliorg" url := "http://localhost:9999/api/v2/query?org=beieliorg"
data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") data := []byte(fmt.Sprintf(`from(bucket:"beielibucket")
|> range(start:-365d) |> range(start:-365d)
|> filter(fn: (r) => r.deveui == "%s") |> 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") |> 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)) req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil { if err != nil {
log.Fatal("Error reading request. ", err) 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 // Set headers
client := &http.Client{Timeout: time.Second * 10} req.Header.Set("Authorization", "Token OzSltiHLmm3WCaFPI0DrK0VFAVCiqcORNrGsgHO43jb0qodyVGAumJQ3HRtkaze53BVR3AmHqfkmrwrjq-xTyA==")
req.Header.Set("accept", "application/csv")
req.Header.Set("content-type", "application/vnd.flux")
// Send request // Set client timeout
resp, err := client.Do(req) client := &http.Client{Timeout: time.Second * 10}
if err != nil {
log.Fatal("Error reading response. ", err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status) // Send request
fmt.Println("response Headers:", resp.Header) resp, err := client.Do(req)
if err != nil {
log.Fatal("Error reading response. ", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) fmt.Println("response Status:", resp.Status)
if err != nil { fmt.Println("response Headers:", resp.Header)
log.Fatal("Error reading body. ", err)
} body, err := ioutil.ReadAll(resp.Body)
fmt.Println("response Body:", string(body)) if err != nil {
log.Fatal("Error reading body. ", err)
scanner := bufio.NewScanner(strings.NewReader(string(body))) }
location, err := time.LoadLocation("Europe/Zurich") fmt.Println("response Body:", string(body))
for scanner.Scan() {
s := strings.Split(scanner.Text(),",") scanner := bufio.NewScanner(strings.NewReader(string(body)))
if ((len(s) >= 7) && !(strings.HasPrefix(s[5],"_"))) { location, err := time.LoadLocation("Europe/Zurich")
mytime,err := time.Parse(time.RFC3339,s[5]) for scanner.Scan() {
if err != nil { s := strings.Split(scanner.Text(), ",")
continue if (len(s) >= 7) && !(strings.HasPrefix(s[5], "_")) {
} mytime, err := time.Parse(time.RFC3339, s[5])
res.Timestamp = mytime.In(location).Format("02.01.2006 15:04") if err != nil {
value := s[6] continue
field := s[7] }
if field == "t" { res.Timestamp = mytime.In(location).Format("02.01.2006 15:04")
res.Temperature = value value := s[6]
} else if field == "h" { field := s[7]
res.Humidity = value if field == "t" {
} else if field == "w" { res.Temperature = value
res.Weight = value } else if field == "h" {
i, err := strconv.Atoi(value) res.Humidity = value
if (err == nil) { } else if field == "w" {
res.Weight_kg = fmt.Sprintf("%.2f",float64(i) / 1000.0) res.Weight = value
} else { i, err := strconv.Atoi(value)
res.Weight_kg = "ERR" if err == nil {
} res.Weight_kg = fmt.Sprintf("%.2f", float64(i)/1000.0)
} else if field == "p" { } else {
res.Pressure = value res.Weight_kg = "ERR"
} else if field == "vp" { }
res.BatteryPercent = value } 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.Deveui = deveui
res.ActiveUntil = getActiveUntil(deveui) res.Alias = getDevAlias(deveui)
res.DaysUntilDeactivated = CalcDaysUntil(res.ActiveUntil) res.Alarmactive = getDevAlarmactive(deveui)
return res res.Smsnumber = getDevSmsnumber(deveui)
res.ActiveUntil = getActiveUntil(deveui)
res.DaysUntilDeactivated = CalcDaysUntil(res.ActiveUntil)
return res
} }

View File

@ -1,13 +1,13 @@
package main package main
import ( import (
"time"
"strings"
"fmt"
"log"
"crypto/rand" "crypto/rand"
"fmt"
"github.com/gomodule/redigo/redis"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"github.com/gomodule/redigo/redis" "log"
"strings"
"time"
) )
var globalPool *redis.Pool var globalPool *redis.Pool
@ -44,18 +44,18 @@ func ping(c redis.Conn) error {
return err return err
} }
logit("PING Response = "+s) logit("PING Response = " + s)
// Output: PONG // Output: PONG
return nil return nil
} }
type Dev struct { type Dev struct {
Deveui string Deveui string
Alias string Alias string
Alarmactive string Alarmactive string
Smsnumber string Smsnumber string
ActiveUntil string // Abo bezahlt bis TT.MM.YYYY ActiveUntil string // Abo bezahlt bis TT.MM.YYYY
} }
func initDB() { func initDB() {
@ -64,17 +64,17 @@ func initDB() {
pool := newPool() pool := newPool()
// get a connection from the globalPool (redis.Conn) // get a connection from the globalPool (redis.Conn)
conn := pool.Get() conn := pool.Get()
defer conn.Close() defer conn.Close()
globalPool = pool globalPool = pool
// wir machen einen Connection Test // wir machen einen Connection Test
ping(conn) ping(conn)
// Wir legen einen initialen Admin User an, falls es diesen noch nicht gibt // Wir legen einen initialen Admin User an, falls es diesen noch nicht gibt
if checkUserAvailable("joerg.lehmann@nbit.ch") { if checkUserAvailable("joerg.lehmann@nbit.ch") {
insertUser("joerg.lehmann@nbit.ch","changeme123","Y"); insertUser("joerg.lehmann@nbit.ch", "changeme123", "Y")
} }
} }
@ -82,10 +82,9 @@ func closeDB() {
globalPool.Close() globalPool.Close()
} }
func updateScaleSettings(scaleSettings Dev) error { func updateScaleSettings(scaleSettings Dev) error {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
// SET object // SET object
_, err := conn.Do("HMSET", devPrefix+scaleSettings.Deveui, "alias", scaleSettings.Alias, "alarmactive", scaleSettings.Alarmactive, "smsnumber", scaleSettings.Smsnumber) _, 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 return nil
} }
func checkUserAvailable(username string) bool { func checkUserAvailable(username string) bool {
logit("checkUserAvailable: User: "+username) logit("checkUserAvailable: User: " + username)
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
_, err := redis.String(conn.Do("GET", userPrefix+username)) _, err := redis.String(conn.Do("GET", userPrefix+username))
if (err == redis.ErrNil) { if err == redis.ErrNil {
logit("User does not exist and is therefore available:"+username) logit("User does not exist and is therefore available:" + username)
return true return true
} else if err != nil { } else if err != nil {
logit("checkUserAvailable: Error to query Key Value Store") logit("checkUserAvailable: Error to query Key Value Store")
return false return false
} }
return false return false
} }
func getMyDevs(username string) []string { func getMyDevs(username string) []string {
res := []string{} res := []string{}
if username == "" { if username == "" {
return res return res
} }
conn := globalPool.Get()
defer conn.Close()
conn := globalPool.Get() logit("getMyDevs: User: " + username)
defer conn.Close()
logit("getMyDevs: User: "+username)
mydevs, err := redis.String(conn.Do("HGET", userPrefix+username, "my_devs")) mydevs, err := redis.String(conn.Do("HGET", userPrefix+username, "my_devs"))
if err == nil { if err == nil {
logit("getMyDevs: mydevs: "+mydevs) logit("getMyDevs: mydevs: " + mydevs)
res = strings.Split(mydevs, ",") res = strings.Split(mydevs, ",")
} else { } else {
log.Print(err) log.Print(err)
} }
return res return res
} }
func getDevAlias(deveui string) string { func getDevAlias(deveui string) string {
res := deveui res := deveui
if deveui == "" { if deveui == "" {
return res return res
} }
conn := globalPool.Get()
defer conn.Close()
conn := globalPool.Get() logit("getDevAlias: Deveui: " + deveui)
defer conn.Close()
logit("getDevAlias: Deveui: "+deveui)
alias, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alias")) alias, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alias"))
if err == nil { if err == nil {
logit("getDevAlias: alias: "+alias) logit("getDevAlias: alias: " + alias)
res = alias res = alias
} else { } else {
log.Print(err) log.Print(err)
} }
return res return res
} }
func getDevAlarmactive(deveui string) string { func getDevAlarmactive(deveui string) string {
res := "0" res := "0"
if deveui == "" { if deveui == "" {
return res return res
} }
conn := globalPool.Get()
defer conn.Close()
conn := globalPool.Get() logit("getDevAlarmactive: Deveui: " + deveui)
defer conn.Close()
logit("getDevAlarmactive: Deveui: "+deveui)
alarmactive, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alarmactive")) alarmactive, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alarmactive"))
if err == nil { if err == nil {
logit("getDevAlarmactive: alarmactive: "+alarmactive) logit("getDevAlarmactive: alarmactive: " + alarmactive)
res = alarmactive res = alarmactive
} else { } else {
log.Print(err) log.Print(err)
} }
return res return res
} }
func getDevSmsnumber(deveui string) string { func getDevSmsnumber(deveui string) string {
res := "+4179XXXXXXX" res := "+4179XXXXXXX"
if deveui == "" { if deveui == "" {
return res return res
} }
conn := globalPool.Get()
defer conn.Close()
conn := globalPool.Get() logit("getDevSmsnumber: Deveui: " + deveui)
defer conn.Close()
logit("getDevSmsnumber: Deveui: "+deveui)
smsnumber, err := redis.String(conn.Do("HGET", devPrefix+deveui, "smsnumber")) smsnumber, err := redis.String(conn.Do("HGET", devPrefix+deveui, "smsnumber"))
if err == nil { if err == nil {
logit("getDevAlarmactive: smsnumber: "+smsnumber) logit("getDevAlarmactive: smsnumber: " + smsnumber)
res = smsnumber res = smsnumber
} else { } else {
log.Print(err) log.Print(err)
} }
return res return res
} }
func getActiveUntil(deveui string) string { func getActiveUntil(deveui string) string {
res := "" res := ""
if deveui == "" { if deveui == "" {
return res return res
} }
conn := globalPool.Get()
defer conn.Close()
conn := globalPool.Get() logit("getActiveUntil: Deveui: " + deveui)
defer conn.Close()
logit("getActiveUntil: Deveui: "+deveui)
activeuntil, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until")) activeuntil, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until"))
if err == nil { if err == nil {
logit("getActiveUntil: activeuntil: "+activeuntil) logit("getActiveUntil: activeuntil: " + activeuntil)
res = activeuntil res = activeuntil
} else { } else {
log.Print(err) log.Print(err)
} }
return res return res
} }
func AboExpired(deveui string) bool { func AboExpired(deveui string) bool {
active_until := getActiveUntil(deveui); active_until := getActiveUntil(deveui)
layout := "02.01.2006"
t, _ := time.Parse(layout, active_until)
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) { func prolongActivation(deveui string, years int) (string, error) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
active_until_old, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until")) active_until_old, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until"))
if err == nil { if err == nil {
logit("prolongActivation: active_until: " +active_until_old) logit("prolongActivation: active_until: " + active_until_old)
} else { } else {
log.Print(err) log.Print(err)
} }
layout := "02.01.2006" layout := "02.01.2006"
t, err := time.Parse(layout, active_until_old) t, err := time.Parse(layout, active_until_old)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
fmt.Println(t.Unix()) fmt.Println(t.Unix())
var t_new time.Time var t_new time.Time
if t.Before(time.Now()) { if t.Before(time.Now()) {
t_new = time.Now().AddDate(years, 0, 0) t_new = time.Now().AddDate(years, 0, 0)
} else { } else {
t_new = t.AddDate(years, 0, 0) t_new = t.AddDate(years, 0, 0)
} }
active_until_new := t_new.Format(layout) active_until_new := t_new.Format(layout)
// SET object // SET object
_, err1 := conn.Do("HMSET", devPrefix+deveui, "active_until", active_until_new) _, err1 := conn.Do("HMSET", devPrefix+deveui, "active_until", active_until_new)
if err1 != nil { if err1 != nil {
return "",err1 return "", err1
} }
return active_until_new, nil return active_until_new, nil
} }
func randString(n int) string { func randString(n int) string {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n) var bytes = make([]byte, n)
rand.Read(bytes) rand.Read(bytes)
for i, b := range bytes { for i, b := range bytes {
bytes[i] = alphanum[b % byte(len(alphanum))] bytes[i] = alphanum[b%byte(len(alphanum))]
} }
return string(bytes) return string(bytes)
} }
func insertUser(username,password,is_admin string) { func insertUser(username, password, is_admin string) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
logit("insertUser: "+username) logit("insertUser: " + username)
pwd := []byte(password) pwd := []byte(password)
hashedPassword,err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost) hashedPassword, err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost)
if err != nil { if err != nil {
logit("insertUser: Error with bcrypt.GenerateFromPassword, User: "+username) logit("insertUser: Error with bcrypt.GenerateFromPassword, User: " + username)
return 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 { if err != nil {
logit("insertUser: Error inserting User: "+username) logit("insertUser: Error inserting User: " + username)
return return
} }
} }
func updateUser(username,password string) { func updateUser(username, password string) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
logit("updateUser: "+username) logit("updateUser: " + username)
pwd := []byte(password) pwd := []byte(password)
hashedPassword,err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost) hashedPassword, err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost)
if err != nil { if err != nil {
logit("updateUser: Error with bcrypt.GenerateFromPassword, User: "+username) logit("updateUser: Error with bcrypt.GenerateFromPassword, User: " + username)
return return
} }
confirm_id := randString(30) confirm_id := randString(30)
_, err = conn.Do("HMSET", userPrefix+username, "new_password", string(hashedPassword), "confirm_id", confirm_id) _, err = conn.Do("HMSET", userPrefix+username, "new_password", string(hashedPassword), "confirm_id", confirm_id)
if err != nil { if err != nil {
logit("updateUser: Error updateing User: "+username) logit("updateUser: Error updateing User: " + username)
return return
} }
_, err = conn.Do("SET", confirmPrefix+confirm_id,username) _, err = conn.Do("SET", confirmPrefix+confirm_id, username)
if err != nil { if err != nil {
logit("updateUser: Error inserting confirm_id: "+confirm_id+": "+username) logit("updateUser: Error inserting confirm_id: " + confirm_id + ": " + username)
return return
} }
sendEmail(username,confirm_id) sendEmail(username, confirm_id)
} }
func checkLoginCredentials(username,password string) bool { func checkLoginCredentials(username, password string) bool {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() 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")) pwd, err := redis.String(conn.Do("HGET", userPrefix+username, "password"))
if err == nil { if err == nil {
logit("checkLoginCredentials: pwd: "+pwd+" CMD: HGET "+userPrefix+username+userPrefix+username+" confirm_id") logit("checkLoginCredentials: pwd: " + pwd + " CMD: HGET " + userPrefix + username + userPrefix + username + " confirm_id")
cid, err := redis.String(conn.Do("HGET", userPrefix+username, "confirm_id")) cid, err := redis.String(conn.Do("HGET", userPrefix+username, "confirm_id"))
if err == nil { if err == nil {
logit("checkLoginCredentials: cid: "+cid) logit("checkLoginCredentials: cid: " + cid)
if !(err != nil && cid != "") { if !(err != nil && cid != "") {
logit("checkLoginCredentials: pwd: "+pwd) logit("checkLoginCredentials: pwd: " + pwd)
if err != nil { if err != nil {
return false return false
} }
} }
} }
} else { } else {
log.Print(err) log.Print(err)
return false return false
} }
hashedPassword := []byte(pwd) hashedPassword := []byte(pwd)
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password)) err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password))
return err == nil return err == nil
} }
func updateLoginTime(username string) { func updateLoginTime(username string) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
_, err := conn.Do("HSET", userPrefix+username, "last_login", time.Now().UTC().Format("2006-01-02 15:04:05")) _, err := conn.Do("HSET", userPrefix+username, "last_login", time.Now().UTC().Format("2006-01-02 15:04:05"))
if err != nil { if err != nil {
logit("updateUser: Error updateing User: "+username) logit("updateUser: Error updateing User: " + username)
return return
} }
} }
func confirmUser(confirm_id string) { func confirmUser(confirm_id string) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()
u, err := redis.String(conn.Do("GET", confirmPrefix+confirm_id)) u, err := redis.String(conn.Do("GET", confirmPrefix+confirm_id))
if err != nil { if err != nil {
logit("confirmUser: Error with searching confirm_id: "+confirm_id) logit("confirmUser: Error with searching confirm_id: " + confirm_id)
return return
} }
new_password, err := redis.String(conn.Do("HGET", userPrefix+u, "new_password")) new_password, err := redis.String(conn.Do("HGET", userPrefix+u, "new_password"))
if err != nil { if err != nil {
logit("confirmUser: Error with getting new_password: "+u) logit("confirmUser: Error with getting new_password: " + u)
return return
} }
_, err = conn.Do("HMSET", userPrefix+u, "confirm_id", "", "password", new_password) _, err = conn.Do("HMSET", userPrefix+u, "confirm_id", "", "password", new_password)
if err != nil { if err != nil {
logit("confirmUser: Error updateing User: "+u) logit("confirmUser: Error updateing User: " + u)
return return
} }
_, err = conn.Do("DEL", confirmPrefix+confirm_id) _, err = conn.Do("DEL", confirmPrefix+confirm_id)
if err != nil { if err != nil {
logit("confirmUser: Error deleting confirm_id: "+confirm_id) logit("confirmUser: Error deleting confirm_id: " + confirm_id)
return return
} }
} }

176
scales.go
View File

@ -1,109 +1,109 @@
package main package main
import ( import (
"fmt" "fmt"
"log" "log"
"regexp" "net/http"
"net/http" "regexp"
) )
// scales handler // scales handler
func save_scale_settingsHandler(response http.ResponseWriter, request *http.Request) { func save_scale_settingsHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request) name := getUserName(request)
if name != "" { if name != "" {
deveui, ok := request.URL.Query()["deveui"] deveui, ok := request.URL.Query()["deveui"]
if !ok || len(deveui[0]) < 1 { if !ok || len(deveui[0]) < 1 {
log.Println("Url Param 'deveui' is missing") log.Println("Url Param 'deveui' is missing")
fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"deveui must be specified in URL\" }") fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"deveui must be specified in URL\" }")
return return
} }
// Query()["deveui"] will return an array of items, // Query()["deveui"] will return an array of items,
// we only want the single item. // we only want the single item.
mydeveui := deveui[0] 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
}
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 'deveui' is: " + string(mydeveui))
log.Println("Url Param 'alias' is missing")
fmt.Fprintf(response, "{ \"rc\": 3, \"msg\": \"alias must be specified in URL\" }")
return
}
myalias := alias[0]
// validate alias alias, ok2 := request.URL.Query()["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"]
if !ok3 || len(alarmactive[0]) < 1 { if !ok2 || len(alias[0]) < 1 {
log.Println("Url Param 'alarmactive' is missing") log.Println("Url Param 'alias' is missing")
fmt.Fprintf(response, "{ \"rc\": 4, \"msg\": \"alarmactive must be specified in URL\" }") fmt.Fprintf(response, "{ \"rc\": 3, \"msg\": \"alias must be specified in URL\" }")
return return
} }
myalarmactive := alarmactive[0] myalias := alias[0]
if !((myalarmactive == "0") || (myalarmactive == "1")) { // validate alias
log.Println("Url Param 'alarmactive' is not valid") match, _ := regexp.MatchString("^[a-zA-Z0-9 ]{1,16}$", myalias)
fmt.Fprintf(response, "{ \"rc\": 10, \"msg\": \"alarmactive is not valid\" }") if !(match) {
return log.Println("Url Param 'alias' is not valid")
} fmt.Fprintf(response, "{ \"rc\": 9, \"msg\": \"alias is not valid\" }")
return
smsnumber, ok4 := request.URL.Query()["smsnumber"] }
if !ok4 || len(smsnumber[0]) < 1 { alarmactive, ok3 := request.URL.Query()["alarmactive"]
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 !ok3 || len(alarmactive[0]) < 1 {
if !(match1) { log.Println("Url Param 'alarmactive' is missing")
log.Println("Url Param 'smsnumber' is not valid") fmt.Fprintf(response, "{ \"rc\": 4, \"msg\": \"alarmactive must be specified in URL\" }")
fmt.Fprintf(response, "{ \"rc\": 11, \"msg\": \"smsnumber is not valid, must be in in format +41791234567\" }") return
return }
} myalarmactive := alarmactive[0]
var mydev Dev if !((myalarmactive == "0") || (myalarmactive == "1")) {
mydev.Deveui = mydeveui log.Println("Url Param 'alarmactive' is not valid")
mydev.Alias = myalias fmt.Fprintf(response, "{ \"rc\": 10, \"msg\": \"alarmactive is not valid\" }")
mydev.Alarmactive = myalarmactive return
mydev.Smsnumber = mysmsnumber }
// now we try to save the settings smsnumber, ok4 := request.URL.Query()["smsnumber"]
err := updateScaleSettings(mydev)
if !ok4 || len(smsnumber[0]) < 1 {
if err != nil { log.Println("Url Param 'smsnumber' is missing")
log.Println("Error to Update Device Settings") fmt.Fprintf(response, "{ \"rc\": 5, \"msg\": \"smsnumber must be specified in URL\" }")
fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"error with saving device settings\" }") return
return }
} else { mysmsnumber := smsnumber[0]
fmt.Fprintf(response, "{ \"rc\": 0, \"msg\": \"SUCCESS\" }")
} match1, _ := regexp.MatchString(`^\+[0-9]{11,11}$`, mysmsnumber)
if !(match1) {
} else { log.Println("Url Param 'smsnumber' is not valid")
fmt.Fprintf(response, "{ \"rc\": 7, \"msg\": \"Only available for logged in users\" }") 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\" }")
}
} }

192
stripe.go
View File

@ -1,119 +1,125 @@
package main package main
import ( import (
"fmt" "encoding/json"
"log" "fmt"
"os" "github.com/stripe/stripe-go"
"io/ioutil" "github.com/stripe/stripe-go/paymentintent"
"encoding/json" "io/ioutil"
"net/http" "log"
"strings" "net/http"
"strconv" "os"
"github.com/stripe/stripe-go" "strconv"
"github.com/stripe/stripe-go/paymentintent" "strings"
) )
func getStripeKey() string { func getStripeKey() string {
return "sk_test_GJbXPD0IAFNvvGpNEpaeDfhl" return "sk_test_GJbXPD0IAFNvvGpNEpaeDfhl"
} }
func getstripepaymentintentHandler(response http.ResponseWriter, request *http.Request) { func getstripepaymentintentHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request) name := getUserName(request)
if name != "" { if name != "" {
charge_data, ok := request.URL.Query()["charge_data"] charge_data, ok := request.URL.Query()["charge_data"]
if !ok || len(charge_data[0]) < 1 { if !ok || len(charge_data[0]) < 1 {
log.Println("Url Param 'charge_data' is missing") log.Println("Url Param 'charge_data' is missing")
fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"charge_data must be specified in URL\" }") fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"charge_data must be specified in URL\" }")
return return
} }
scales := strings.Split(charge_data[0],",") scales := strings.Split(charge_data[0], ",")
var abo_years = 0 var abo_years = 0
var items []string var items []string
for _,scale := range scales { for _, scale := range scales {
items = strings.Split(scale,":") items = strings.Split(scale, ":")
if (len(items) == 2) { if len(items) == 2 {
abo_count, err := strconv.Atoi(items[1]) abo_count, err := strconv.Atoi(items[1])
if err == nil { if err == nil {
abo_years += abo_count abo_years += abo_count
} }
} }
} }
abo_amount := int64(abo_years * 2400) abo_amount := int64(abo_years * 2400)
stripe.Key = getStripeKey() stripe.Key = getStripeKey()
params := &stripe.PaymentIntentParams{ params := &stripe.PaymentIntentParams{
Amount: stripe.Int64(abo_amount), Amount: stripe.Int64(abo_amount),
Currency: stripe.String(string(stripe.CurrencyCHF)), Currency: stripe.String(string(stripe.CurrencyCHF)),
ReceiptEmail: stripe.String(name), ReceiptEmail: stripe.String(name),
} }
params.AddMetadata("charge_data", charge_data[0]) params.AddMetadata("charge_data", charge_data[0])
paymentintent, err := paymentintent.New(params) 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)
}
} else { if err != nil {
fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"Only available for logged in users\" }") 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) { func HandlePayment(user string, charge_data string, amount int64) {
fmt.Printf("HandlePayment for %s (charge_data: %s, amount: %d)!\n", user, charge_data, amount) fmt.Printf("HandlePayment for %s (charge_data: %s, amount: %d)!\n", user, charge_data, amount)
for _, token := range strings.Split(charge_data,",") { charge_data_email_text := fmt.Sprintf("%-30s %20s %10s\n", "Alias", "verlängern bis", "Betrag")
res := strings.Split(token,":") charge_data_email_text = charge_data_email_text + strings.Repeat("-", 62) + "\n"
if (len(res)) == 2 { for _, token := range strings.Split(charge_data, ",") {
deveui := res[0] res := strings.Split(token, ":")
years, _ := strconv.Atoi(res[1]) if (len(res)) == 2 {
fmt.Printf("prolongActivation %s: %d\n", deveui, years) deveui := res[0]
prolongActivation(deveui, years) years, _ := strconv.Atoi(res[1])
} fmt.Printf("prolongActivation %s: %d\n", deveui, years)
} prolongActivation(deveui, years)
sendPaymentConfirmationEmail(user,charge_data,amount) 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) { func stripeWebhookHandler(w http.ResponseWriter, req *http.Request) {
const MaxBodyBytes = int64(65536) const MaxBodyBytes = int64(65536)
req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes) req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes)
payload, err := ioutil.ReadAll(req.Body) payload, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err) fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable) w.WriteHeader(http.StatusServiceUnavailable)
return return
} }
event := stripe.Event{} event := stripe.Event{}
if err := json.Unmarshal(payload, &event); err != nil { if err := json.Unmarshal(payload, &event); err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error()) fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error())
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
// Unmarshal the event data into an appropriate struct depending on its Type // Unmarshal the event data into an appropriate struct depending on its Type
switch event.Type { switch event.Type {
case "payment_intent.succeeded": case "payment_intent.succeeded":
var paymentIntent stripe.PaymentIntent var paymentIntent stripe.PaymentIntent
err := json.Unmarshal(event.Data.Raw, &paymentIntent) err := json.Unmarshal(event.Data.Raw, &paymentIntent)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
fmt.Printf("PaymentIntent was successful (charge_data: %s, amount: %d)!\n", paymentIntent.Metadata["charge_data"], paymentIntent.Amount) 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) HandlePayment(paymentIntent.ReceiptEmail, paymentIntent.Metadata["charge_data"], paymentIntent.Amount)
// ... handle other event types // ... handle other event types
default: default:
fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type) fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }