From fbc9fc15841960f322b4391e97dd8154b056db72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20M=C3=BCller?= Date: Mon, 18 Sep 2017 23:59:01 +0200 Subject: [PATCH] fraud detection added --- assets/templates/form.html | 1 + assets/templates/note.html | 1 + server.go | 18 +++++++++++++++++- storage.go | 12 +++++++++++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/assets/templates/form.html b/assets/templates/form.html index 9a2e314..a44de7d 100644 --- a/assets/templates/form.html +++ b/assets/templates/form.html @@ -22,6 +22,7 @@ diff --git a/assets/templates/note.html b/assets/templates/note.html index fe7af7c..baf3203 100644 --- a/assets/templates/note.html +++ b/assets/templates/note.html @@ -8,6 +8,7 @@ + {{.Ads}}
{{.Content}}
diff --git a/server.go b/server.go index 6fc9edd..b3294c5 100644 --- a/server.go +++ b/server.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net/http" "net/url" + "os" "sync" "database/sql" @@ -17,7 +18,10 @@ import ( "github.com/labstack/gommon/log" ) -var stats = &sync.Map{} +var ( + stats = &sync.Map{} + ads []byte +) type Template struct{ templates *template.Template } @@ -35,6 +39,15 @@ func main() { } defer db.Close() + adsFName := os.Getenv("ADS") + if adsFName != "" { + var err error + ads, err = ioutil.ReadFile(adsFName) + if err != nil { + e.Logger.Errorf("couldn't read file %q: %v", adsFName, err) + } + } + e.Renderer = &Template{templates: template.Must(template.ParseGlob("assets/templates/*.html"))} e.File("/favicon.ico", "assets/public/favicon.ico") @@ -61,6 +74,9 @@ func main() { } } defer stats.Store(n.ID, views+1) + if n.Fraud() { + n.Ads = mdTmplHTML(ads) + } c.Logger().Debugf("/%q requested; response code: %d", n.ID, code) return c.Render(code, "Note", n) }) diff --git a/storage.go b/storage.go index f9c1176..4228ec2 100644 --- a/storage.go +++ b/storage.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "html/template" + "math" "math/rand" "net/http" "regexp" @@ -25,6 +26,7 @@ func init() { const ( idLength = 5 statsSavingInterval = 1 * time.Minute + fraudThreshold = 7 ) var ( @@ -39,6 +41,7 @@ var ( rexpNewLine = regexp.MustCompile("[\n\r]") rexpNonAlphaNum = regexp.MustCompile("[`~!@#$%^&*_|+=?;:'\",.<>{}\\/]") rexpNoScriptIframe = regexp.MustCompile("<.*?(iframe|script).*?>") + rexpLink = regexp.MustCompile("(ht|f)tp://[^\\s]+") errorUnathorised = errors.New("id or password is wrong") errorBadRequest = errors.New("password is empty") @@ -48,7 +51,7 @@ type Note struct { ID, Title, Text, Password string Published, Edited time.Time Views int - Content template.HTML + Content, Ads template.HTML } func errPage(code int, details ...string) Note { @@ -203,3 +206,10 @@ var mdRenderer = markdown.New(markdown.HTML(true)) func mdTmplHTML(content []byte) template.HTML { return template.HTML(mdRenderer.RenderToString(content)) } + +func (n *Note) Fraud() bool { + stripped := rexpLink.ReplaceAllString(n.Text, "") + l1 := len(n.Text) + l2 := len(stripped) + return int(math.Ceil(100*float64(l1-l2)/float64(l1))) > fraudThreshold +}