Browse Source

fraud detection added

master
Christian Müller 8 years ago
parent
commit
fbc9fc1584
  1. 1
      assets/templates/form.html
  2. 1
      assets/templates/note.html
  3. 18
      server.go
  4. 12
      storage.go

1
assets/templates/form.html

@ -22,6 +22,7 @@
</fieldset> </fieldset>
</form> </form>
<footer> <footer>
<a href="/">&#8962; notehub</a> &middot;
<a href="https://github.com/chmllr/NoteHub">source code</a> &middot; <a href="https://github.com/chmllr/NoteHub">source code</a> &middot;
<a href="/TOS.md">terms of service</a> <a href="/TOS.md">terms of service</a>
</footer> </footer>

1
assets/templates/note.html

@ -8,6 +8,7 @@
<link href="/style.css" rel="stylesheet" type="text/css" /> <link href="/style.css" rel="stylesheet" type="text/css" />
</head> </head>
<body> <body>
{{.Ads}}
<article> <article>
{{.Content}} {{.Content}}
</article> </article>

18
server.go

@ -7,6 +7,7 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"os"
"sync" "sync"
"database/sql" "database/sql"
@ -17,7 +18,10 @@ import (
"github.com/labstack/gommon/log" "github.com/labstack/gommon/log"
) )
var stats = &sync.Map{} var (
stats = &sync.Map{}
ads []byte
)
type Template struct{ templates *template.Template } type Template struct{ templates *template.Template }
@ -35,6 +39,15 @@ func main() {
} }
defer db.Close() 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.Renderer = &Template{templates: template.Must(template.ParseGlob("assets/templates/*.html"))}
e.File("/favicon.ico", "assets/public/favicon.ico") e.File("/favicon.ico", "assets/public/favicon.ico")
@ -61,6 +74,9 @@ func main() {
} }
} }
defer stats.Store(n.ID, views+1) 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) c.Logger().Debugf("/%q requested; response code: %d", n.ID, code)
return c.Render(code, "Note", n) return c.Render(code, "Note", n)
}) })

12
storage.go

@ -7,6 +7,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"html/template" "html/template"
"math"
"math/rand" "math/rand"
"net/http" "net/http"
"regexp" "regexp"
@ -25,6 +26,7 @@ func init() {
const ( const (
idLength = 5 idLength = 5
statsSavingInterval = 1 * time.Minute statsSavingInterval = 1 * time.Minute
fraudThreshold = 7
) )
var ( var (
@ -39,6 +41,7 @@ var (
rexpNewLine = regexp.MustCompile("[\n\r]") rexpNewLine = regexp.MustCompile("[\n\r]")
rexpNonAlphaNum = regexp.MustCompile("[`~!@#$%^&*_|+=?;:'\",.<>{}\\/]") rexpNonAlphaNum = regexp.MustCompile("[`~!@#$%^&*_|+=?;:'\",.<>{}\\/]")
rexpNoScriptIframe = regexp.MustCompile("<.*?(iframe|script).*?>") rexpNoScriptIframe = regexp.MustCompile("<.*?(iframe|script).*?>")
rexpLink = regexp.MustCompile("(ht|f)tp://[^\\s]+")
errorUnathorised = errors.New("id or password is wrong") errorUnathorised = errors.New("id or password is wrong")
errorBadRequest = errors.New("password is empty") errorBadRequest = errors.New("password is empty")
@ -48,7 +51,7 @@ type Note struct {
ID, Title, Text, Password string ID, Title, Text, Password string
Published, Edited time.Time Published, Edited time.Time
Views int Views int
Content template.HTML Content, Ads template.HTML
} }
func errPage(code int, details ...string) Note { func errPage(code int, details ...string) Note {
@ -203,3 +206,10 @@ var mdRenderer = markdown.New(markdown.HTML(true))
func mdTmplHTML(content []byte) template.HTML { func mdTmplHTML(content []byte) template.HTML {
return template.HTML(mdRenderer.RenderToString(content)) 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
}

Loading…
Cancel
Save