From 64be5b2f25428a04dcfcb9b317318aa36a10ef4c Mon Sep 17 00:00:00 2001 From: Yang Luo Date: Mon, 17 Aug 2020 17:38:48 +0800 Subject: [PATCH] Add RuleTimeConflict. --- controllers/impression.go | 6 +++++- detect/check_bot.go | 7 ++++++- detect/rule.go | 3 +++ detect/rule_overspeed.go | 2 +- detect/rule_time_conflict.go | 28 ++++++++++++++++++++++++++++ detect/util.go | 10 +++++++++- trace/session.go | 2 +- util/string.go | 4 ++++ 8 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 detect/rule_time_conflict.go diff --git a/controllers/impression.go b/controllers/impression.go index ede7404..890d3d4 100644 --- a/controllers/impression.go +++ b/controllers/impression.go @@ -32,7 +32,11 @@ func (c *APIController) GetImpressionsAll() { } func (c *APIController) GetImpression() { - c.Data["json"] = trace.GetImpression(c.Input().Get("id"), c.Input().Get("websiteId")) + impression := trace.GetImpression(c.Input().Get("id"), c.Input().Get("websiteId")) + + detect.CheckBotForImpression(impression) + + c.Data["json"] = impression c.ServeJSON() } diff --git a/detect/check_bot.go b/detect/check_bot.go index d12e6a6..f452601 100644 --- a/detect/check_bot.go +++ b/detect/check_bot.go @@ -11,7 +11,12 @@ func checkBot(events []*trace.Event) (int, string, int, int, int) { // return isBot, reason, rule, start, end //} - isBot, reason, rule, start, end := checkOverspeed(events) + isBot, reason, rule, start, end := checkTimeConflict(events) + if isBot != 0 { + return isBot, reason, rule, start, end + } + + isBot, reason, rule, start, end = checkOverspeed(events) if isBot != 0 { return isBot, reason, rule, start, end } diff --git a/detect/rule.go b/detect/rule.go index 769d204..1520337 100644 --- a/detect/rule.go +++ b/detect/rule.go @@ -13,6 +13,7 @@ const ( RuleRootlessClick RuleHighPointDensity RuleNegativeCursor + RuleTimeConflict RuleUpperLimit ) @@ -38,6 +39,8 @@ func GetRuleName(rule int) string { return "Point density too high" case RuleNegativeCursor: return "Negative cursor found" + case RuleTimeConflict: + return "Time conflict found" default: return "" } diff --git a/detect/rule_overspeed.go b/detect/rule_overspeed.go index 0bfe477..1e2d79b 100644 --- a/detect/rule_overspeed.go +++ b/detect/rule_overspeed.go @@ -14,7 +14,7 @@ var SpeedLimit = 1000.0 func checkOverspeed(events []*trace.Event) (int, string, int, int, int) { dist := 0.0 for i := 0; i < len(events) - 1; i ++ { - dist += getDistance(events[i].X, events[i].Y, events[i+1].X, events[i+1].Y) + dist += getDistance(events[i], events[i+1]) } time := events[len(events) - 1].Timestamp - events[0].Timestamp diff --git a/detect/rule_time_conflict.go b/detect/rule_time_conflict.go new file mode 100644 index 0000000..f825984 --- /dev/null +++ b/detect/rule_time_conflict.go @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +package detect + +import ( + "fmt" + "github.com/microsoft/mouselog/trace" + "github.com/microsoft/mouselog/util" +) + +func checkTimeConflict(events []*trace.Event) (int, string, int, int, int) { + moveEvents := []*trace.Event{} + for _, event := range events { + if event.Type == "mousemove" || event.Type == "touchmove" { + moveEvents = append(moveEvents, event) + } + } + + for i := 0; i < len(moveEvents)-1; i++ { + if moveEvents[i].Timestamp == moveEvents[i+1].Timestamp { + return 1, fmt.Sprintf("same timestamp: %s for two events: %d and %d", util.FormatFloat(moveEvents[i].Timestamp), i, i+1), RuleTimeConflict, i, i + 2 + + } + } + + return 0, ReasonNone, RuleNone, -1, -1 +} diff --git a/detect/util.go b/detect/util.go index 4280815..097e6e2 100644 --- a/detect/util.go +++ b/detect/util.go @@ -9,7 +9,15 @@ import ( "github.com/microsoft/mouselog/trace" ) -func getDistance(x1 int, y1 int, x2 int, y2 int) float64 { +func getSpeed(e1 *trace.Event, e2 *trace.Event) float64 { + return getDistanceRaw(e1.X, e1.Y, e2.X, e2.Y) / (e2.Timestamp - e1.Timestamp) +} + +func getDistance(e1 *trace.Event, e2 *trace.Event) float64 { + return getDistanceRaw(e1.X, e1.Y, e2.X, e2.Y) +} + +func getDistanceRaw(x1 int, y1 int, x2 int, y2 int) float64 { return math.Sqrt(float64((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))) } diff --git a/trace/session.go b/trace/session.go index a6bbdfa..3d75f5f 100644 --- a/trace/session.go +++ b/trace/session.go @@ -180,7 +180,7 @@ func (ss *Session) AddTrace(t *Trace) { func (ss *Session) ToJson() *SessionJson { ruleCounts := []int{} - for i := 0; i < 9; i++ { + for i := 0; i < 10; i++ { ruleCounts = append(ruleCounts, 0) } for _, impression := range ss.Impressions { diff --git a/util/string.go b/util/string.go index 0e8395d..37e5033 100644 --- a/util/string.go +++ b/util/string.go @@ -26,6 +26,10 @@ func ParseFloat(s string) float64 { return f } +func FormatFloat(f float64) string { + return strconv.FormatFloat(f, 'f', -1, 64) +} + func UnescapeUserAgent(userAgent string) string { return strings.Replace(userAgent, "#TAB#", ",", -1) }