fraud detection added
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
<footer>
|
<footer>
|
||||||
|
<a href="/">⌂ notehub</a> ·
|
||||||
<a href="https://github.com/chmllr/NoteHub">source code</a> ·
|
<a href="https://github.com/chmllr/NoteHub">source code</a> ·
|
||||||
<a href="/TOS.md">terms of service</a>
|
<a href="/TOS.md">terms of service</a>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
})
|
})
|
||||||
|
|||||||
+11
-1
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user