package util import ( "fmt" "html/template" "log" "net/url" "strings" "github.com/gomarkdown/markdown" "github.com/microcosm-cc/bluemonday" // "errors") /* util.Eout example invocationsif err != nil { return util.Eout(err, "reading data")}if err = util.Eout(err, "reading data"); err != nil { return nil, err}*/ type ErrorDescriber struct { environ string // the basic context that is potentially generating errors (like a GetThread function, the environ would be "get thread")} // parametrize Eout/Check such that error messages contain a defined context/environfunc Describe(environ string) ErrorDescriber { return ErrorDescriber{environ}} func (ed ErrorDescriber) Eout(err error, msg string, args ...interface{}) error { msg = fmt.Sprintf("%s: %s", ed.environ, msg) return Eout(err, msg, args...)} func (ed ErrorDescriber) Check(err error, msg string, args ...interface{}) { msg = fmt.Sprintf("%s: %s", ed.environ, msg) Check(err, msg, args...)} // format all errors consistently, and provide context for the error using the string `msg`func Eout(err error, msg string, args ...interface{}) error { if err != nil { // received an invocation of e.g. format: // Eout(err, "reading data for %s and %s", "database item", "weird user") if len(args) > 0 { return fmt.Errorf("%s (%w)", fmt.Sprintf(msg, args...), err) } return fmt.Errorf("%s (%w)", msg, err) } return nil} func Check(err error, msg string, args ...interface{}) { if len(args) > 0 { err = Eout(err, msg, args...) } else { err = Eout(err, msg) } if err != nil { log.Fatalln(err) }} func Contains(slice []string, s string) bool { for _, item := range slice { if item == s { return true } } return false} var contentGuardian = bluemonday.UGCPolicy()var strictContentGuardian = bluemonday.StrictPolicy() // Turns Markdown input into HTMLfunc Markup(md template.HTML) template.HTML { mdBytes := []byte(string(md)) // fix newlines mdBytes = markdown.NormalizeNewlines(mdBytes) maybeUnsafeHTML := markdown.ToHTML(mdBytes, nil, nil) // guard against malicious code being embedded html := contentGuardian.SanitizeBytes(maybeUnsafeHTML) return template.HTML(html)} func SanitizeStringStrict(s string) string { return strictContentGuardian.Sanitize(s)} // make a string be suitable for use as part of a urlfunc SanitizeURL(input string) string { input = strings.ReplaceAll(input, " ", "-") input = url.PathEscape(input) // TODO(2022-01-08): evaluate use of strict content guardian? return strings.ToLower(input)}
package util
import (
"fmt"
"html/template"
"log"
"net/url"
"strings"
"github.com/gomarkdown/markdown"
"github.com/microcosm-cc/bluemonday"
// "errors"
)
/* util.Eout example invocations
if err != nil {
return util.Eout(err, "reading data")
}
if err = util.Eout(err, "reading data"); err != nil {
return nil, err
}
*/
type ErrorDescriber struct {
environ string // the basic context that is potentially generating errors (like a GetThread function, the environ would be "get thread")
}
// parametrize Eout/Check such that error messages contain a defined context/environ
func Describe(environ string) ErrorDescriber {
return ErrorDescriber{environ}
}
func (ed ErrorDescriber) Eout(err error, msg string, args ...interface{}) error {
msg = fmt.Sprintf("%s: %s", ed.environ, msg)
return Eout(err, msg, args...)
}
func (ed ErrorDescriber) Check(err error, msg string, args ...interface{}) {
msg = fmt.Sprintf("%s: %s", ed.environ, msg)
Check(err, msg, args...)
}
// format all errors consistently, and provide context for the error using the string `msg`
func Eout(err error, msg string, args ...interface{}) error {
if err != nil {
// received an invocation of e.g. format:
// Eout(err, "reading data for %s and %s", "database item", "weird user")
if len(args) > 0 {
return fmt.Errorf("%s (%w)", fmt.Sprintf(msg, args...), err)
}
return fmt.Errorf("%s (%w)", msg, err)
}
return nil
}
func Check(err error, msg string, args ...interface{}) {
if len(args) > 0 {
err = Eout(err, msg, args...)
} else {
err = Eout(err, msg)
}
if err != nil {
log.Fatalln(err)
}
}
func Contains(slice []string, s string) bool {
for _, item := range slice {
if item == s {
return true
}
}
return false
}
var contentGuardian = bluemonday.UGCPolicy()
var strictContentGuardian = bluemonday.StrictPolicy()
// Turns Markdown input into HTML
func Markup(md template.HTML) template.HTML {
mdBytes := []byte(string(md))
// fix newlines
mdBytes = markdown.NormalizeNewlines(mdBytes)
maybeUnsafeHTML := markdown.ToHTML(mdBytes, nil, nil)
// guard against malicious code being embedded
html := contentGuardian.SanitizeBytes(maybeUnsafeHTML)
return template.HTML(html)
}
func SanitizeStringStrict(s string) string {
return strictContentGuardian.Sanitize(s)
}
// make a string be suitable for use as part of a url
func SanitizeURL(input string) string {
input = strings.ReplaceAll(input, " ", "-")
input = url.PathEscape(input)
// TODO(2022-01-08): evaluate use of strict content guardian?
return strings.ToLower(input)
}