aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2024-10-31 22:37:31 +0300
committerArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2024-10-31 22:37:31 +0300
commitd7da8f133146de4fba1db13bfbc63242c917f817 (patch)
tree319e5216b05e279149e26c3b5cb50e6c88773e27
parentbackend: better auth check, audit logging (diff)
downloadlphub-d7da8f133146de4fba1db13bfbc63242c917f817.tar.gz
lphub-d7da8f133146de4fba1db13bfbc63242c917f817.tar.bz2
lphub-d7da8f133146de4fba1db13bfbc63242c917f817.zip
backend: add rate limiting
-rw-r--r--backend/api/rate.go20
-rw-r--r--backend/api/routes.go28
-rw-r--r--backend/go.mod1
-rw-r--r--backend/go.sum2
4 files changed, 37 insertions, 14 deletions
diff --git a/backend/api/rate.go b/backend/api/rate.go
new file mode 100644
index 0000000..1e262af
--- /dev/null
+++ b/backend/api/rate.go
@@ -0,0 +1,20 @@
1package api
2
3import (
4 "net/http"
5
6 "golang.org/x/time/rate"
7
8 "github.com/gin-gonic/gin"
9)
10
11func RateLimit(c *gin.Context) {
12 limiter := rate.NewLimiter(1, 5) // don't know if this is too much or not enough tbh
13 if limiter.Allow() {
14 c.Next()
15 } else {
16 c.AbortWithStatusJSON(http.StatusTooManyRequests, gin.H{
17 "error": "Rate limit exceeded",
18 })
19 }
20}
diff --git a/backend/api/routes.go b/backend/api/routes.go
index ecfb54b..c3124f9 100644
--- a/backend/api/routes.go
+++ b/backend/api/routes.go
@@ -18,29 +18,29 @@ func InitRoutes(router *gin.Engine) {
18 c.File("docs/index.html") 18 c.File("docs/index.html")
19 }) 19 })
20 // Tokens, login 20 // Tokens, login
21 v1.GET("/token", handlers.GetCookie) 21 v1.GET("/token", RateLimit, handlers.GetCookie)
22 v1.DELETE("/token", handlers.DeleteCookie) 22 v1.DELETE("/token", RateLimit, handlers.DeleteCookie)
23 v1.GET("/login", handlers.Login) 23 v1.GET("/login", RateLimit, handlers.Login)
24 // Users, profiles 24 // Users, profiles
25 v1.GET("/profile", IsAuthenticated, handlers.Profile) 25 v1.GET("/profile", RateLimit, IsAuthenticated, handlers.Profile)
26 v1.PUT("/profile", IsAuthenticated, handlers.UpdateCountryCode) 26 v1.PUT("/profile", IsAuthenticated, handlers.UpdateCountryCode)
27 v1.POST("/profile", IsAuthenticated, handlers.UpdateUser) 27 v1.POST("/profile", IsAuthenticated, handlers.UpdateUser)
28 v1.GET("/users/:userid", IsAuthenticated, handlers.FetchUser) 28 v1.GET("/users/:userid", IsAuthenticated, handlers.FetchUser)
29 // Maps 29 // Maps
30 // - Summary 30 // - Summary
31 v1.GET("/maps/:mapid/summary", handlers.FetchMapSummary) 31 v1.GET("/maps/:mapid/summary", RateLimit, handlers.FetchMapSummary)
32 v1.POST("/maps/:mapid/summary", IsAuthenticated, handlers.CreateMapSummary) 32 v1.POST("/maps/:mapid/summary", IsAuthenticated, handlers.CreateMapSummary)
33 v1.PUT("/maps/:mapid/summary", IsAuthenticated, handlers.EditMapSummary) 33 v1.PUT("/maps/:mapid/summary", IsAuthenticated, handlers.EditMapSummary)
34 v1.DELETE("/maps/:mapid/summary", IsAuthenticated, handlers.DeleteMapSummary) 34 v1.DELETE("/maps/:mapid/summary", IsAuthenticated, handlers.DeleteMapSummary)
35 v1.PUT("/maps/:mapid/image", IsAuthenticated, handlers.EditMapImage) 35 v1.PUT("/maps/:mapid/image", IsAuthenticated, handlers.EditMapImage)
36 // - Leaderboards 36 // - Leaderboards
37 v1.GET("/maps/:mapid/leaderboards", handlers.FetchMapLeaderboards) 37 v1.GET("/maps/:mapid/leaderboards", RateLimit, handlers.FetchMapLeaderboards)
38 v1.POST("/maps/:mapid/record", IsAuthenticated, handlers.CreateRecordWithDemo) 38 v1.POST("/maps/:mapid/record", IsAuthenticated, handlers.CreateRecordWithDemo)
39 v1.DELETE("/maps/:mapid/record/:recordid", IsAuthenticated, handlers.DeleteRecord) 39 v1.DELETE("/maps/:mapid/record/:recordid", IsAuthenticated, handlers.DeleteRecord)
40 v1.GET("/demos", handlers.DownloadDemoWithID) 40 v1.GET("/demos", RateLimit, handlers.DownloadDemoWithID)
41 // - Discussions 41 // - Discussions
42 v1.GET("/maps/:mapid/discussions", handlers.FetchMapDiscussions) 42 v1.GET("/maps/:mapid/discussions", RateLimit, handlers.FetchMapDiscussions)
43 v1.GET("/maps/:mapid/discussions/:discussionid", handlers.FetchMapDiscussion) 43 v1.GET("/maps/:mapid/discussions/:discussionid", RateLimit, handlers.FetchMapDiscussion)
44 v1.POST("/maps/:mapid/discussions", IsAuthenticated, handlers.CreateMapDiscussion) 44 v1.POST("/maps/:mapid/discussions", IsAuthenticated, handlers.CreateMapDiscussion)
45 v1.POST("/maps/:mapid/discussions/:discussionid", IsAuthenticated, handlers.CreateMapDiscussionComment) 45 v1.POST("/maps/:mapid/discussions/:discussionid", IsAuthenticated, handlers.CreateMapDiscussionComment)
46 v1.PUT("/maps/:mapid/discussions/:discussionid", IsAuthenticated, handlers.EditMapDiscussion) 46 v1.PUT("/maps/:mapid/discussions/:discussionid", IsAuthenticated, handlers.EditMapDiscussion)
@@ -50,12 +50,12 @@ func InitRoutes(router *gin.Engine) {
50 v1.GET("/rankings/steam", handlers.RankingsSteam) 50 v1.GET("/rankings/steam", handlers.RankingsSteam)
51 v1.GET("/search", handlers.SearchWithQuery) 51 v1.GET("/search", handlers.SearchWithQuery)
52 // Games, chapters, maps 52 // Games, chapters, maps
53 v1.GET("/games", handlers.FetchGames) 53 v1.GET("/games", RateLimit, handlers.FetchGames)
54 v1.GET("/games/:gameid", handlers.FetchChapters) 54 v1.GET("/games/:gameid", RateLimit, handlers.FetchChapters)
55 v1.GET("/chapters/:chapterid", handlers.FetchChapterMaps) 55 v1.GET("/chapters/:chapterid", RateLimit, handlers.FetchChapterMaps)
56 v1.GET("/games/:gameid/maps", handlers.FetchMaps) 56 v1.GET("/games/:gameid/maps", RateLimit, handlers.FetchMaps)
57 // Logs 57 // Logs
58 v1.GET("/logs/score", handlers.ScoreLogs) 58 v1.GET("/logs/score", RateLimit, handlers.ScoreLogs)
59 // v1.GET("/logs/mod", IsAuthenticated, handlers.ModLogs) 59 // v1.GET("/logs/mod", IsAuthenticated, handlers.ModLogs)
60 } 60 }
61} 61}
diff --git a/backend/go.mod b/backend/go.mod
index f6eef48..17308f3 100644
--- a/backend/go.mod
+++ b/backend/go.mod
@@ -14,6 +14,7 @@ require (
14 github.com/swaggo/files v1.0.1 14 github.com/swaggo/files v1.0.1
15 github.com/swaggo/gin-swagger v1.6.0 15 github.com/swaggo/gin-swagger v1.6.0
16 github.com/swaggo/swag v1.16.3 16 github.com/swaggo/swag v1.16.3
17 golang.org/x/time v0.6.0
17) 18)
18 19
19require ( 20require (
diff --git a/backend/go.sum b/backend/go.sum
index 10504e4..647f6f9 100644
--- a/backend/go.sum
+++ b/backend/go.sum
@@ -219,6 +219,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
219golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 219golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
220golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= 220golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
221golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 221golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
222golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
223golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
222golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 224golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
223golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 225golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
224golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 226golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=