From 2e6ae483d01691cac4f1c05db0c5f733600bec52 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Tue, 17 Jan 2017 17:54:11 +0100 Subject: [PATCH] Don't allow requesting beatmaps if already requested in the previous five minutes --- cmd/cheesegull-api/main.go | 1 + http/api/beatmap.go | 14 +++++++++++++- http/ctx/context.go | 1 + http/server.go | 2 ++ providers/redis/new.go | 1 + providers/redis/system.go | 16 ++++++++++++++++ system.go | 8 ++++++++ 7 files changed, 42 insertions(+), 1 deletion(-) diff --git a/cmd/cheesegull-api/main.go b/cmd/cheesegull-api/main.go index 2b2e59f..0cb4049 100644 --- a/cmd/cheesegull-api/main.go +++ b/cmd/cheesegull-api/main.go @@ -113,6 +113,7 @@ func execute(c *cli.Context) error { Communication: red, APISecret: sec, FileResolver: fileresolvers.FileSystem{}, + Logging: red, }) fmt.Println("Listening on", port) diff --git a/http/api/beatmap.go b/http/api/beatmap.go index 54a65f1..f577e0f 100644 --- a/http/api/beatmap.go +++ b/http/api/beatmap.go @@ -24,7 +24,19 @@ func RequestBeatmap(w http.ResponseWriter, r *http.Request, c *ctx.Context) { return } - err := c.Communication.SendBeatmapRequest(i) + l5m, err := c.Logging.UpdateInLast5Minutes(i) + if err != nil { + c.HandleError(err) + j(w, 200, aec) + return + } + if l5m { + resp.Message = "that beatmap was already requested in the last 5 minutes!" + j(w, 200, resp) + return + } + + err = c.Communication.SendBeatmapRequest(i) if err != nil { c.HandleError(err) j(w, 500, aec) diff --git a/http/ctx/context.go b/http/ctx/context.go index 5691fba..aa0627a 100644 --- a/http/ctx/context.go +++ b/http/ctx/context.go @@ -17,6 +17,7 @@ type Context struct { BeatmapService cheesegull.BeatmapService FileResolver cheesegull.FileResolver Communication cheesegull.CommunicationService + Logging cheesegull.Logging ErrorHandler func(error) Request *http.Request } diff --git a/http/server.go b/http/server.go index 9cf6d03..6415266 100644 --- a/http/server.go +++ b/http/server.go @@ -18,6 +18,7 @@ type Options struct { BeatmapService cheesegull.BeatmapService FileResolver cheesegull.FileResolver Communication cheesegull.CommunicationService + Logging cheesegull.Logging APISecret string } @@ -74,6 +75,7 @@ func (o Options) req(a func(w http.ResponseWriter, r *http.Request, c *ctx.Conte BeatmapService: o.BeatmapService, FileResolver: o.FileResolver, Communication: o.Communication, + Logging: o.Logging, Request: r, }) fmt.Printf("%v | %-12v %-4s %-15s\n", start.Format("2006-01-02 15:04:05"), diff --git a/providers/redis/new.go b/providers/redis/new.go index 37fbb05..382d1f2 100644 --- a/providers/redis/new.go +++ b/providers/redis/new.go @@ -9,6 +9,7 @@ import ( type Provided interface { cheesegull.CommunicationService cheesegull.SystemService + cheesegull.Logging } type impl struct { diff --git a/providers/redis/system.go b/providers/redis/system.go index a71844c..3f77c6f 100644 --- a/providers/redis/system.go +++ b/providers/redis/system.go @@ -1,5 +1,10 @@ package redis +import ( + "fmt" + "time" +) + func (i *impl) GetSecurityKey(def string) string { k := i.Get("system:security_key").Val() if k == "" { @@ -8,3 +13,14 @@ func (i *impl) GetSecurityKey(def string) string { } return k } + +func (i *impl) UpdateInLast5Minutes(b int) (bool, error) { + v := i.Exists(fmt.Sprintf("updates:5m:%d", b)) + if v.Err() != nil { + return false, v.Err() + } + if !v.Val() { + i.Set(fmt.Sprintf("updates:5m:%d", b), nil, time.Minute*5) + } + return v.Val(), nil +} diff --git a/system.go b/system.go index 1f065b1..83a4764 100644 --- a/system.go +++ b/system.go @@ -9,3 +9,11 @@ type SystemService interface { // the one currently stored does not exist. GetSecurityKey(def string) string } + +// Logging is a service that logs in a database certain information. +type Logging interface { + // UpdateInLast5Minutes checks whether a beatmap (i) was requested an update + // in the previous 5 minutes, and if it wasn't it records the update being + // requested. + UpdateInLast5Minutes(i int) (bool, error) +} -- GitLab