Skip to content

Commit

Permalink
Email report contains links to web server
Browse files Browse the repository at this point in the history
  • Loading branch information
rothskeller committed Feb 4, 2023
1 parent eaef557 commit 52cf597
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 12 deletions.
1 change: 1 addition & 0 deletions wppsvr/analyze/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ jurisdictions:
Sunnyvale: SNY
Unincorporated: XSC

serverURL: https://none
listenAddr: none

# These are the details for sending email messages via SMTP (e.g. for reports).
Expand Down
1 change: 1 addition & 0 deletions wppsvr/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Config struct {
MessageTypes map[string]*MessageTypeConfig `yaml:"messageTypes"`
ProblemActions map[string]string `yaml:"problems"`
Jurisdictions map[string]string `yaml:"jurisdictions"`
ServerURL string `yaml:"serverURL"`
ListenAddr string `yaml:"listenAddr"`
SMTP *SMTPConfig `yaml:"smtp"`
CanViewEveryone []string `yaml:"canViewEveryone"`
Expand Down
10 changes: 10 additions & 0 deletions wppsvr/config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"net"
"net/mail"
"net/url"
"regexp"
"strings"

Expand Down Expand Up @@ -268,6 +269,15 @@ func (c *Config) Validate(knownProbs map[string]string) (valid bool) {
}
}

// Check that we have a URL for the web server.
if c.ServerURL == "" {
log.Printf("ERROR: config.serverURL is not specified")
valid = false
} else if u, err := url.Parse(c.ServerURL); err != nil || u.Scheme != "https" {
log.Printf("ERROR: config.serverURL has an invalid value, not an https:// URL")
valid = false
}

// Check that we have a listen address for the web server.
if c.ListenAddr == "" {
log.Printf("ERROR: config.listenAddr is not specified")
Expand Down
10 changes: 8 additions & 2 deletions wppsvr/report/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,21 @@ func (r *Report) emailStatistics(w *quotedprintable.Writer) {

func (r *Report) emailMessages(w *quotedprintable.Writer) {
var hasMultiple bool
var serverURL = config.Get().ServerURL

io.WriteString(w, `<div style="max-width:640px;margin-bottom:24px"><div style="font-size:20px;font-weight:bold;color:#444">Messages</div><table cellspacing="0" cellpadding="0">`)
for _, m := range r.Messages {
var multiple string
fmt.Fprintf(w, `<tr><td style="padding-top:4px;text-align:right">%s</td><td style="padding-top:4px;font-weight:bold">%s</td>`, html.EscapeString(m.Prefix), html.EscapeString(m.Suffix))
if m.Multiple {
multiple, hasMultiple = `*`, true
}
fmt.Fprintf(w, `<td style="padding:4px 0 0 16px">%s%s</td><td style="padding:4px 0 0 16px">%s</td><td style="padding:4px 0 0 16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:%s">%s%s</td></tr>`,
m.Source, multiple, m.Jurisdiction, classColor[m.Class], classLabel[m.Class], m.Problem)
fmt.Fprintf(w, `<td style="padding:4px 0 0 16px">%s%s</td><td style="padding:4px 0 0 16px">%s</td><td style="padding:4px 0 0 16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:%s">%s`,
m.Source, multiple, m.Jurisdiction, classColor[m.Class], classLabel[m.Class])
if m.Problem != "" {
fmt.Fprintf(w, `%s [<a href="%s/message?hash=%s">details</a>]`, m.Problem, serverURL, m.Hash)
}
fmt.Fprint(w, `</td></tr>`)
}
io.WriteString(w, `</table>`)
if hasMultiple {
Expand Down
1 change: 1 addition & 0 deletions wppsvr/report/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ func generateMessages(r *Report, session *store.Session, messages []*store.Messa
var rm Message

rm.ID = m.LocalID
rm.Hash = m.Hash
rm.FromCallSign = m.FromCallSign
if len(m.FromCallSign) > 2 {
if m.FromCallSign[1] >= '0' && m.FromCallSign[1] <= '9' {
Expand Down
1 change: 1 addition & 0 deletions wppsvr/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type Count struct {
// A Message contains the information about a single message in a Report.
type Message struct {
ID string
Hash string
FromCallSign string
Prefix string
Suffix string
Expand Down
25 changes: 25 additions & 0 deletions wppsvr/store/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,31 @@ func (st *Store) GetMessage(localID string) *Message {
return &m
}

// GetMessageByHash returns the message with the specified hash, or nil if there
// is none.
func (st *Store) GetMessageByHash(hash string) *Message {
var (
m Message
problems string
err error
)
m.Hash = hash
st.mutex.RLock()
defer st.mutex.RUnlock()
err = st.dbh.QueryRow("SELECT id, session, deliverytime, message, fromaddress, fromcallsign, frombbs, tobbs, jurisdiction, messagetype, subject, problems, actions FROM message WHERE hash=?", hash).
Scan(&m.LocalID, &m.Session, &m.DeliveryTime, &m.Message, &m.FromAddress, &m.FromCallSign, &m.FromBBS, &m.ToBBS, &m.Jurisdiction, &m.MessageType, &m.Subject, &problems, &m.Actions)
switch err {
case nil:
break
case sql.ErrNoRows:
return nil
default:
panic(err)
}
m.Problems = split(problems)
return &m
}

// GetSessionMessages returns the set of messages received for the session, in
// the order they were delivered to the BBS at which they were received.
func (st *Store) GetSessionMessages(sessionID int) (messages []*Message) {
Expand Down
27 changes: 17 additions & 10 deletions wppsvr/webserver/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,23 @@ func (ws *webserver) serveMessage(w http.ResponseWriter, r *http.Request) {
responses []*store.Response
content int
)
if callsign = checkLoggedIn(w, r); callsign == "" {
return
}
if message = ws.st.GetMessage(r.FormValue("id")); message == nil {
http.Error(w, "404 Not Found", http.StatusNotFound)
return
}
if message.FromCallSign != callsign && !canViewEveryone(callsign) {
http.Error(w, "403 Forbidden", http.StatusForbidden)
return
if hash := r.FormValue("hash"); hash != "" {
if message = ws.st.GetMessageByHash(hash); message == nil {
http.Error(w, "404 Not Found", http.StatusNotFound)
return
}
} else {
if callsign = checkLoggedIn(w, r); callsign == "" {
return
}
if message = ws.st.GetMessage(r.FormValue("id")); message == nil {
http.Error(w, "404 Not Found", http.StatusNotFound)
return
}
if message.FromCallSign != callsign && !canViewEveryone(callsign) {
http.Error(w, "403 Forbidden", http.StatusForbidden)
return
}
}
responses = ws.st.GetResponses(message.LocalID)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
Expand Down

0 comments on commit 52cf597

Please sign in to comment.