From 00150118d2239ea32b0696694ef074a23d3e61e9 Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Thu, 25 Apr 2019 20:47:20 +0200 Subject: [PATCH] graph2: Added complexity to prevent queries that can take down the server. --- cmd/rpdata-server/main.go | 9 +- graph2/complexity.go | 178 ++++++++++++++++++++++++++++++++++++++ graph2/graph.go | 3 +- 3 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 graph2/complexity.go diff --git a/cmd/rpdata-server/main.go b/cmd/rpdata-server/main.go index 9f18f62..3d51f05 100644 --- a/cmd/rpdata-server/main.go +++ b/cmd/rpdata-server/main.go @@ -8,15 +8,13 @@ import ( "runtime/debug" "strings" - "git.aiterp.net/rpdata/api/models" - "git.aiterp.net/rpdata/api/models/changes" - - "git.aiterp.net/rpdata/api/models/logs" - "git.aiterp.net/rpdata/api/graph2" "git.aiterp.net/rpdata/api/internal/auth" "git.aiterp.net/rpdata/api/internal/loader" "git.aiterp.net/rpdata/api/internal/store" + "git.aiterp.net/rpdata/api/models" + "git.aiterp.net/rpdata/api/models/changes" + "git.aiterp.net/rpdata/api/models/logs" "github.com/99designs/gqlgen/handler" ) @@ -82,6 +80,7 @@ func queryHandler() http.HandlerFunc { return fmt.Errorf("The server failed to serve your request due to an internal error, it has been logged") }), + handler.ComplexityLimit(300), ) return func(w http.ResponseWriter, r *http.Request) { diff --git a/graph2/complexity.go b/graph2/complexity.go new file mode 100644 index 0000000..6179884 --- /dev/null +++ b/graph2/complexity.go @@ -0,0 +1,178 @@ +package graph2 + +import ( + input "git.aiterp.net/rpdata/api/graph2/input" + changes "git.aiterp.net/rpdata/api/models/changes" + channels "git.aiterp.net/rpdata/api/models/channels" + characters "git.aiterp.net/rpdata/api/models/characters" + files "git.aiterp.net/rpdata/api/models/files" + logs "git.aiterp.net/rpdata/api/models/logs" + posts "git.aiterp.net/rpdata/api/models/posts" + stories "git.aiterp.net/rpdata/api/models/stories" +) + +func complexity() (cr ComplexityRoot) { + subListComplexity := 25 + bigSublistComplexity := 75 + hugeSublistComplexity := 100 + findComplexity := 100 + listComplexity := 200 + mutationComplexity := 100 + + cr.Query.Character = func(childComplexity int, id *string, nick *string) int { + return childComplexity + findComplexity + } + cr.Query.Characters = func(childComplexity int, filter *characters.Filter) int { + return childComplexity + listComplexity + } + cr.Query.Channel = func(childComplexity int, name string) int { + return childComplexity + findComplexity + } + cr.Query.Channels = func(childComplexity int, filter *channels.Filter) int { + return childComplexity + listComplexity + } + cr.Query.Post = func(childComplexity int, id string) int { + return childComplexity + findComplexity + } + cr.Query.Posts = func(childComplexity int, filter *posts.Filter) int { + return childComplexity + listComplexity + } + cr.Query.UnknownNicks = func(childComplexity int, filter *input.UnknownNicksFilter) int { + return childComplexity + listComplexity + } + cr.Query.Log = func(childComplexity int, id string) int { + return childComplexity + findComplexity + } + cr.Query.Logs = func(childComplexity int, filter *logs.Filter) int { + return childComplexity + listComplexity + } + cr.Query.Chapter = func(childComplexity int, id string) int { + return childComplexity + findComplexity + } + cr.Query.Comment = func(childComplexity int, id string) int { + return childComplexity + findComplexity + } + cr.Query.Tags = func(childComplexity int) int { + return childComplexity + listComplexity + } + cr.Query.Story = func(childComplexity int, id string) int { + return childComplexity + findComplexity + } + cr.Query.Stories = func(childComplexity int, filter *stories.Filter) int { + return childComplexity + listComplexity + } + cr.Query.File = func(childComplexity int, id string) int { + return childComplexity + findComplexity + } + cr.Query.Files = func(childComplexity int, filter *files.Filter) int { + return childComplexity + listComplexity + } + cr.Query.Changes = func(childComplexity int, filter *changes.Filter) int { + return childComplexity + listComplexity + } + cr.Query.Token = func(childComplexity int) int { + return childComplexity + findComplexity + } + + cr.Mutation.AddStory = func(childComplexity int, input input.StoryAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddStoryTag = func(childComplexity int, input input.StoryTagAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveStoryTag = func(childComplexity int, input input.StoryTagRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditStory = func(childComplexity int, input input.StoryEditInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveStory = func(childComplexity int, input input.StoryRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddChapter = func(childComplexity int, input input.ChapterAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditChapter = func(childComplexity int, input input.ChapterEditInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.MoveChapter = func(childComplexity int, input input.ChapterMoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveChapter = func(childComplexity int, input input.ChapterRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddComment = func(childComplexity int, input input.CommentAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditComment = func(childComplexity int, input input.CommentEditInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveComment = func(childComplexity int, input input.CommentRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddLog = func(childComplexity int, input input.LogAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.ImportLog = func(childComplexity int, input input.LogImportInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditLog = func(childComplexity int, input input.LogEditInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveLog = func(childComplexity int, input input.LogRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddPost = func(childComplexity int, input input.PostAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditPost = func(childComplexity int, input input.PostEditInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.MovePost = func(childComplexity int, input input.PostMoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemovePost = func(childComplexity int, input input.PostRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddCharacter = func(childComplexity int, input input.CharacterAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddCharacterNick = func(childComplexity int, input input.CharacterNickInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveCharacterNick = func(childComplexity int, input input.CharacterNickInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditCharacter = func(childComplexity int, input input.CharacterEditInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.RemoveCharacter = func(childComplexity int, input input.CharacterRemoveInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.AddChannel = func(childComplexity int, input input.ChannelAddInput) int { + return childComplexity + mutationComplexity + } + cr.Mutation.EditChannel = func(childComplexity int, input input.ChannelEditInput) int { + return childComplexity + mutationComplexity + } + + cr.Log.Characters = func(childComplexity int) int { + return childComplexity + subListComplexity + } + cr.Log.Posts = func(childComplexity int, kinds []string) int { + return childComplexity + hugeSublistComplexity + } + + cr.Story.Chapters = func(childComplexity int) int { + return childComplexity + bigSublistComplexity + } + cr.Story.Tags = func(childComplexity int) int { + return childComplexity + subListComplexity + } + + cr.Chapter.Comments = func(childComplexity int, limit *int) int { + return childComplexity + subListComplexity + } + + return +} diff --git a/graph2/graph.go b/graph2/graph.go index 607a6a0..680e998 100644 --- a/graph2/graph.go +++ b/graph2/graph.go @@ -12,7 +12,8 @@ import ( // New creates a new GraphQL schema. func New() graphql.ExecutableSchema { return NewExecutableSchema(Config{ - Resolvers: &rootResolver{}, + Resolvers: &rootResolver{}, + Complexity: complexity(), }) }