hivedav

A curlable free/busy scheduler with CalDAV integration
git clone https://git.in0rdr.ch/hivedav.git
Log | Files | Refs | Pull requests |Archive | README | LICENSE

commit b05c5987a99dfc92ba7df3c16add7c216969c70e
parent e44d07bf63ad1b82ee2a03fab29b05b72a0aa0c0
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Fri,  6 Oct 2023 20:36:53 +0200

fix: error msgs and return escaping

Diffstat:
Mserver.go | 82+++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 45 insertions(+), 37 deletions(-)

diff --git a/server.go b/server.go @@ -675,33 +675,36 @@ func (s *Server) BookCubicle(w http.ResponseWriter, req *http.Request, ps httpro return } + dtstart := dtStartPathTimeLocal inputDateTimeFmt := "2006-01-02T15:04" dtStartInput := req.FormValue("dtstart") - // TODO: replace local time by timezone specified in config file - dtStartInputTime, err := time.ParseInLocation(inputDateTimeFmt, dtStartInput, time.Local) - if err != nil { - log.Printf("Error parsing booking dtstart from user input: %v\n", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - log.Printf("dtstart booking request (local time): %v\n", dtStartPathTimeLocal) + if dtStartInput != "" { + // TODO: replace local time by timezone specified in config file + dtStartInputTime, err := time.ParseInLocation(inputDateTimeFmt, dtStartInput, time.Local) + if err != nil { + log.Printf("Error parsing booking dtstart from user input: %v\n", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } - dtstart := dtStartPathTimeLocal - if dtStartPathTimeLocal != dtStartInputTime { - // prefer time slot chosen by the user (html input field) - dtstart = dtStartInputTime - log.Printf("Preferring user input dtstart '%v' from the form\n", dtStartInput) + // prefer time time chosen by the user (html input field) + if dtStartPathTimeLocal != dtStartInputTime { + dtstart = dtStartInputTime + log.Printf("Preferring user input dtstart '%v' from the form\n", dtStartInput) + } } log.Printf("dtStartInput: %v\n", dtStartInput) log.Printf("dtStartPath: %v\n", dtStartPath) + log.Printf("dtstart booking request (local time): %v\n", dtstart) mail := req.FormValue("mail") //msg := req.FormValue("msg") msg := html.UnescapeString(req.FormValue("msg")) if mail == "" || msg == "" { - http.Error(w, fmt.Sprintf("Mail and msg required, try again: 'curl %s/book/%s -F 'mail=' -F 'msg='\n", s.config.HiveDavHost, dtstart), http.StatusBadRequest) + errorMsg := fmt.Sprintf("Mail and msg required, try again: 'curl %s/book/%s -F 'mail=' -F 'msg='\n", s.config.HiveDavHost, dtstart.Format("2006-01-02-15")) + http.Error(w, errorMsg, http.StatusBadRequest) return } @@ -807,6 +810,8 @@ func (s *Server) sendMail(recepient string, msg string, dtstart time.Time) error dstTzOffsetTo = fmt.Sprintf("%+03d00", (offsetHours + 1)) } + foldedMsg := fold(msg) + icsData := IcsData{ Prodid: fmt.Sprintf("-//HiveDAV//%s//EN", hivedavVersion), Uid: strings.ToUpper(uuid), @@ -820,12 +825,13 @@ func (s *Server) sendMail(recepient string, msg string, dtstart time.Time) error DstTzOffsetTo: dstTzOffsetTo, Summary: s.config.BookingSummary, Reminder: s.config.BookingReminder, - Description: fold(msg), + Description: foldedMsg, Location: fmt.Sprintf("%s/%s", s.config.BookingLocation, strings.ToUpper(uuid)), Organizer: s.config.CaldavUser, Attendee: recepient, } + log.Printf("foldedMsg: %s\n", foldedMsg) log.Printf("Description: %s\n", icsData.Description) err = icsTmpl.Execute(icsFile, icsData) @@ -834,15 +840,15 @@ func (s *Server) sendMail(recepient string, msg string, dtstart time.Time) error } e.AttachFile(tmpFilePath) - //lastSlashIndex := strings.LastIndex(tmpFilePath, "/") - //var tmpFileName string - //if lastSlashIndex != -1 { - // tmpFileName = tmpFilePath[lastSlashIndex+1:] - //} + lastSlashIndex := strings.LastIndex(tmpFilePath, "/") + var tmpFileName string + if lastSlashIndex != -1 { + tmpFileName = tmpFilePath[lastSlashIndex+1:] + } // https://datatracker.ietf.org/doc/html/rfc2447#section-2.4 - //e.Attachments[0].ContentType = fmt.Sprintf("text/calendar; charset=utf-8; method=REQUEST; name=%s", tmpFileName) - e.Attachments[0].ContentType = "text/calendar; charset=utf-8; method=REQUEST" - fmt.Println(e.Attachments[0].ContentType) + e.Attachments[0].ContentType = fmt.Sprintf("text/calendar; charset=utf-8; method=REQUEST; name=%s", tmpFileName) + //e.Attachments[0].ContentType = "text/calendar; charset=utf-8; method=REQUEST" + //fmt.Println(e.Attachments[0].ContentType) smtpServer := fmt.Sprintf("%s:%d", s.config.SmtpHost, s.config.SmtpPort) auth := smtp.PlainAuth("", s.config.SmtpUser, s.config.SmtpPassword, s.config.SmtpHost) @@ -881,7 +887,7 @@ func fold(s string) string { escch := rune(0x0) // \0 esc := false - for (i < len(runeStr)-1) || esc { + for (i < len(runeStr)) || esc { buf = append(buf, rune(0x0)) bufl++ @@ -904,11 +910,11 @@ func fold(s string) string { // escape characters // https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.11 switch runeStr[i] { - //case rune(0x5c): // backslash '\' - // buf[bufl-2] = rune(0x5c) - // escch = rune(0x5c) - // esc = true - // break + case rune(0x5c): // backslash '\' + buf[bufl-2] = rune(0x5c) + escch = rune(0x5c) + esc = true + break case rune(0x3b): // semicolon ';' buf[bufl-2] = rune(0x5c) escch = rune(0x3b) @@ -919,12 +925,15 @@ func fold(s string) string { escch = rune(0x2c) esc = true break - //case rune(0xa): // newline '\n' - // buf[bufl-2] = rune(0x5c) // backslash '\' - // escch = rune(0x6e) // literal 'n' - // //escch = rune(0xa) // newline '\n' - // esc = true - // break + case rune(0xa): // newline '\n' + buf[bufl-2] = rune(0x5c) // backslash '\' + escch = rune(0x6e) // literal 'n' + //escch = rune(0xa) // newline '\n' + esc = true + break + case rune(0xd): // carriage return '\r' + buf[bufl-2] = rune(0x20) // whitespace ' ' + break default: // write regular character from runeStr buf[bufl-2] = runeStr[i] @@ -932,12 +941,11 @@ func fold(s string) string { } i++ } - // terminate the char string in any case (esc or not) //buf[bufl-1] = rune(0x0) } - return string(buf) + return string(buf[:len(buf)-1]) } // https://datatracker.ietf.org/doc/html/rfc7986#section-5.3