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
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)
}

View File

@ -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
}

2
log.go
View File

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

82
mail.go
View File

@ -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)
}
}

80
main.go
View File

@ -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)

View File

@ -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
}

View File

@ -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
}
}

176
scales.go
View File

@ -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\" }")
}
}

192
stripe.go
View File

@ -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)
}