From ab87da256c72bc5a85f484c75e14009911c6a87c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Thu, 27 Jun 2024 13:14:37 +0200 Subject: [PATCH] Stricter datetime input --- configuration.go | 21 +++++++++++++++++++++ datapoint.go | 24 ++++++++++++++++++------ helper.go | 11 +++++++++++ main.go | 3 +-- 4 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 helper.go diff --git a/configuration.go b/configuration.go index bf83893..8803069 100644 --- a/configuration.go +++ b/configuration.go @@ -6,9 +6,11 @@ import ( // Standard "database/sql" + "time" ) type Configuration struct { + timezoneLocation *time.Location Settings map[string]string } @@ -36,6 +38,7 @@ func SmonConfigInit() (cfg Configuration, err error) { cfg.Settings[setting] = value } + err = cfg.LoadTimezone() return } @@ -49,6 +52,15 @@ func (cfg *Configuration) Validate() (err error) { return } +func (cfg *Configuration) LoadTimezone() (err error) { + cfg.timezoneLocation, err = time.LoadLocation(cfg.Settings["TIMEZONE"]) + return +} + +func (cfg *Configuration) Timezone() *time.Location { + return cfg.timezoneLocation +} + func (cfg *Configuration) SetTheme(theme string) (err error) { cfg.Settings["THEME"] = theme _, err = service.Db.Conn.Exec(`UPDATE public.configuration SET value=$1 WHERE setting='THEME'`, theme) @@ -57,6 +69,15 @@ func (cfg *Configuration) SetTheme(theme string) (err error) { func (cfg *Configuration) SetTimezone(tz string) (err error) { cfg.Settings["TIMEZONE"] = tz + err = cfg.LoadTimezone() + if err != nil { + return werr.Wrap(err).WithData(tz) + } + _, err = service.Db.Conn.Exec(`UPDATE public.configuration SET value=$1 WHERE setting='TIMEZONE'`, tz) + if err != nil { + return werr.Wrap(err).WithData(tz) + } + return } diff --git a/datapoint.go b/datapoint.go index 55cdae8..3563a5f 100644 --- a/datapoint.go +++ b/datapoint.go @@ -120,8 +120,12 @@ func (dp Datapoint) Update() (err error) { // {{{ } // }}} func DatapointAdd[T any](name string, value T) (err error) { // {{{ - row := service.Db.Conn.QueryRow(`SELECT id, datatype FROM datapoint WHERE name=$1`, name) + type dpRequest = struct { + ID int + value any + } + row := service.Db.Conn.QueryRow(`SELECT id, datatype FROM datapoint WHERE name=$1`, name) var dpID int var dpType DatapointType @@ -140,13 +144,21 @@ func DatapointAdd[T any](name string, value T) (err error) { // {{{ case STRING: _, err = service.Db.Conn.Exec(`INSERT INTO datapoint_value(datapoint_id, value_string) VALUES($1, $2)`, dpID, value) case DATETIME: - _, err = service.Db.Conn.Exec(`INSERT INTO datapoint_value(datapoint_id, value_datetime) VALUES($1, $2)`, dpID, value) + // Time value is required to be a RFC 3339 formatted time string + var t time.Time + valueStr, ok := any(value).([]byte) + if !ok { + return werr.New("DATETIME value not a string").WithData(dpRequest{dpID, value}) + } + t, err = stringToTime(string(valueStr)) + if err != nil { + return werr.Wrap(err).WithData(dpRequest{dpID, value}).Log() + } + + _, err = service.Db.Conn.Exec(`INSERT INTO datapoint_value(datapoint_id, value_datetime) VALUES($1, $2)`, dpID, t) } if err != nil { - err = werr.Wrap(err).WithData(struct { - ID int - value any - }{dpID, value}) + err = werr.Wrap(err).WithData(dpRequest{dpID, value}) return } diff --git a/helper.go b/helper.go new file mode 100644 index 0000000..0dab728 --- /dev/null +++ b/helper.go @@ -0,0 +1,11 @@ +package main + +import ( + // Standard + "time" +) + +func stringToTime(strTime string) (t time.Time, err error) {// {{{ + t, err = time.Parse(time.RFC3339, strTime) + return +}// }}} diff --git a/main.go b/main.go index b462b08..2e6b594 100644 --- a/main.go +++ b/main.go @@ -369,7 +369,7 @@ func getPage(layout, page string) (tmpl *template.Template, err error) { // {{{ funcMap := template.FuncMap{ "format_time": func(t time.Time) template.HTML { return template.HTML( - t.Local().Format(`2006-01-02 15:04:05`), + t.In(smonConfig.Timezone()).Format(`2006-01-02 15:04:05`), ) }, } @@ -739,7 +739,6 @@ func pageDatapointValues(w http.ResponseWriter, r *http.Request, _ *session.T) { return } - logger.Info("FOO", "from", timeFrom, "to", timeTo, "t", timeToParam) page := Page{ LAYOUT: "main", PAGE: "datapoint_values",