graph_attack 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71a5e6c0ce41ca59713a49108f5ebcc3a579aefcd1e95273c495a5ae1e4fd6f6
4
- data.tar.gz: 5430e07ebf58ac5b9addbe8b397f6fd832fa56091112136f8ce972cd2e1fe0aa
3
+ metadata.gz: 8e7c2758ed10d1304e998ecdfb980897aec795513e69eaef79cfcc7b0d42b76f
4
+ data.tar.gz: 286c11e9c2dea795607c3c35d4b662254609ae71b89f3e6d6a17729578900132
5
5
  SHA512:
6
- metadata.gz: cef61dfd8f249877fcdbd6ae1962b6678efd280ef415989d6abe22ebb7e8db68dd164ce47ecce610548ac13352471044741c0bf6918ca050dc2193a5178ab5af
7
- data.tar.gz: fdf832b9e228ccbf8aa66777f2f9334a7c32a25a5435e6017e0ac8073c7c636cd21dc06f0416a8abbf9f063ff30f64f209d55d9979e2eeea27fd7dff4f1ffe84
6
+ metadata.gz: 0ffe6fd28792ec03d9592ac3caf36268dba9c4710cefbe1ab9f4f3913eaf45f610beebaa6a7a183e4593b1e447ae69fd93df4094815231d15dae1b72c6fa1e59
7
+ data.tar.gz: 4e38c3c995f9efe86991d237d27c1b1c0ccc984d4b7870acb3fbd24f204e80881edd337211f47d705919556a3467db08836581982a68b5345f7edd4a2fc2e5d4
data/.rubocop.yml CHANGED
@@ -34,6 +34,13 @@ Gemspec/RequiredRubyVersion:
34
34
  Metrics/MethodLength:
35
35
  Max: 15
36
36
 
37
+ # Limit line length.
38
+ Layout/LineLength:
39
+ Max: 80
40
+ Exclude:
41
+ - bin/rake
42
+ - bin/rubocop
43
+
37
44
  # Allow ASCII comments (e.g "…").
38
45
  Style/AsciiComments:
39
46
  Enabled: false
@@ -102,64 +109,3 @@ Style/RedundantRegexpEscape:
102
109
 
103
110
  Style/SlicingWithRange:
104
111
  Enabled: true
105
-
106
- Gemspec/DateAssignment: # (new in 1.10)
107
- Enabled: true
108
- Layout/SpaceBeforeBrackets: # (new in 1.7)
109
- Enabled: true
110
- Lint/AmbiguousAssignment: # (new in 1.7)
111
- Enabled: true
112
- Lint/DeprecatedConstants: # (new in 1.8)
113
- Enabled: true
114
- Lint/DuplicateBranch: # (new in 1.3)
115
- Enabled: true
116
- Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
117
- Enabled: true
118
- Lint/EmptyBlock: # (new in 1.1)
119
- Enabled: true
120
- Lint/EmptyClass: # (new in 1.3)
121
- Enabled: true
122
- Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
123
- Enabled: true
124
- Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
125
- Enabled: true
126
- Lint/NumberedParameterAssignment: # (new in 1.9)
127
- Enabled: true
128
- Lint/OrAssignmentToConstant: # (new in 1.9)
129
- Enabled: true
130
- Lint/RedundantDirGlobSort: # (new in 1.8)
131
- Enabled: true
132
- Lint/SymbolConversion: # (new in 1.9)
133
- Enabled: true
134
- Lint/ToEnumArguments: # (new in 1.1)
135
- Enabled: true
136
- Lint/TripleQuotes: # (new in 1.9)
137
- Enabled: true
138
- Lint/UnexpectedBlockArity: # (new in 1.5)
139
- Enabled: true
140
- Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
141
- Enabled: true
142
- Style/ArgumentsForwarding: # (new in 1.1)
143
- Enabled: true
144
- Style/CollectionCompact: # (new in 1.2)
145
- Enabled: true
146
- Style/DocumentDynamicEvalDefinition: # (new in 1.1)
147
- Enabled: true
148
- Style/EndlessMethod: # (new in 1.8)
149
- Enabled: true
150
- Style/HashConversion: # (new in 1.10)
151
- Enabled: true
152
- Style/HashExcept: # (new in 1.7)
153
- Enabled: true
154
- Style/IfWithBooleanLiteralBranches: # (new in 1.9)
155
- Enabled: true
156
- Style/NegatedIfElseCondition: # (new in 1.2)
157
- Enabled: true
158
- Style/NilLambda: # (new in 1.3)
159
- Enabled: true
160
- Style/RedundantArgument: # (new in 1.4)
161
- Enabled: true
162
- Style/StringChars: # (new in 1.12)
163
- Enabled: true
164
- Style/SwapValues: # (new in 1.1)
165
- Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  unreleased
2
2
  ----------
3
3
 
4
+ v2.2.0
5
+ ------
6
+
7
+ Feature:
8
+ - Skip throttling when rate limited field is nil (#19)
9
+
10
+ v2.1.0
11
+ ------
12
+
13
+ Feature:
14
+ - Add support to custom rate limited context key with the `on:` option.
15
+
4
16
  v2.0.0
5
17
  ------
6
18
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # GraphAttack
2
2
 
3
- [![CircleCI](https://circleci.com/gh/sunny/graph_attack.svg?style=svg)](https://circleci.com/gh/sunny/graph_attack)
3
+ [![Build Status](https://app.travis-ci.com/sunny/graph_attack.svg?branch=main)](https://app.travis-ci.com/sunny/graph_attack)
4
4
 
5
5
  GraphQL analyser for blocking & throttling.
6
6
 
@@ -58,24 +58,38 @@ class GraphqlController < ApplicationController
58
58
  end
59
59
  ```
60
60
 
61
+ If that key is `nil`, throttling will be disabled.
62
+
61
63
  ## Configuration
62
64
 
63
- Use a custom Redis client instead of the default:
65
+ ### Custom context key
66
+
67
+ If you want to throttle using a different value than the IP address, you can
68
+ choose which context key you want to use with the `on` option. E.g.:
64
69
 
65
70
  ```rb
66
- field :some_expensive_field, String, null: false do
67
- extension GraphAttack::RateLimit,
68
- threshold: 15,
69
- interval: 60,
70
- redis_client: Redis.new(url: "…")
71
- end
71
+ extension GraphAttack::RateLimit,
72
+ threshold: 15,
73
+ interval: 60,
74
+ on: :client_id
75
+ ```
76
+
77
+ ### Custom Redis client
78
+
79
+ Use a custom Redis client instead of the default with the `redis_client` option:
80
+
81
+ ```rb
82
+ extension GraphAttack::RateLimit,
83
+ threshold: 15,
84
+ interval: 60,
85
+ redis_client: Redis.new(url: "…")
72
86
  ```
73
87
 
74
88
  ## Development
75
89
 
76
90
  After checking out the repo, run `bin/setup` to install dependencies. Then, run
77
- `rake` to run the tests and the linter. You can also run `bin/console` for an
78
- interactive prompt that will allow you to experiment.
91
+ `bin/rake` to run the tests and the linter. You can also run `bin/console` for
92
+ an interactive prompt that will allow you to experiment.
79
93
 
80
94
  ## Versionning
81
95
 
@@ -84,10 +98,18 @@ see the tags on this repository.
84
98
 
85
99
  ## Releasing
86
100
 
87
- To release a new version, update the version number in `version.rb`, commit,
88
- and then run `bin/rake release`, which will create a git tag for the version,
89
- push git commits and tags, and push the gem to
90
- [rubygems.org](https://rubygems.org).
101
+ To release a new version, update the version number in `version.rb` and in the
102
+ `CHANGELOG.md`. Update the `README.md` if there are missing segments, make sure
103
+ tests and linting are pristine by calling `bundle && bin/rake`, then create a
104
+ commit for this version, for example with:
105
+
106
+ ```sh
107
+ git add .
108
+ git commit -m v`ruby -rbundler/setup -rgraph_attack/version -e "puts GraphAttack::VERSION"`
109
+ ```
110
+
111
+ You can then run `bin/rake release`, which will assign a git tag, push using
112
+ git, and push the gem to [rubygems.org](https://rubygems.org).
91
113
 
92
114
  ## Contributing
93
115
 
@@ -110,8 +132,8 @@ file for details.
110
132
 
111
133
  ## Authors
112
134
 
113
- - **Fanny Cheung** - [KissKissBankBank](https://github.com/KissKissBankBank)
114
- - **Sunny Ripert** - [KissKissBankBank](https://github.com/KissKissBankBank)
135
+ - [Fanny Cheung](https://github.com/Ynote) — [ynote.hk](https://ynote.hk)
136
+ - [Sunny Ripert](https://github.com/sunny) — [sunfox.org](https://sunfox.org)
115
137
 
116
138
  ## Acknowledgments
117
139
 
data/graph_attack.gemspec CHANGED
@@ -44,11 +44,11 @@ Gem::Specification.new do |spec|
44
44
  spec.add_development_dependency 'rspec_junit_formatter', '~> 0.3'
45
45
 
46
46
  # Ruby code linter.
47
- spec.add_development_dependency 'rubocop', '~> 1.1'
47
+ spec.add_development_dependency 'rubocop', '~> 1.33.0'
48
48
 
49
49
  # RSpec extension for RuboCop.
50
- spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
50
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.12.1'
51
51
 
52
52
  # Rake extension for RuboCop
53
- spec.add_development_dependency 'rubocop-rake'
53
+ spec.add_development_dependency 'rubocop-rake', '~> 0.6.0'
54
54
  end
@@ -3,10 +3,16 @@
3
3
  module GraphAttack
4
4
  class RateLimit < GraphQL::Schema::FieldExtension
5
5
  def resolve(object:, arguments:, **_rest)
6
- ip = object.context[:ip]
7
- raise GraphAttack::Error, 'Missing :ip value on the GraphQL context' unless ip
6
+ rate_limited_field = object.context[rate_limited_key]
8
7
 
9
- return RateLimited.new('Query rate limit exceeded') if calls_exceeded_on_query?(ip)
8
+ unless object.context.key?(rate_limited_key)
9
+ raise GraphAttack::Error,
10
+ "Missing :#{rate_limited_key} key on the GraphQL context"
11
+ end
12
+
13
+ if rate_limited_field && calls_exceeded_on_query?(rate_limited_field)
14
+ return RateLimited.new('Query rate limit exceeded')
15
+ end
10
16
 
11
17
  yield(object, arguments)
12
18
  end
@@ -14,17 +20,16 @@ module GraphAttack
14
20
  private
15
21
 
16
22
  def key
17
- "graphql-query-#{field.name}"
23
+ on = "-#{options[:on]}" if options[:on]
24
+
25
+ "graphql-query-#{field.name}#{on}"
18
26
  end
19
27
 
20
- def calls_exceeded_on_query?(ip)
21
- rate_limit = Ratelimit.new(ip, redis: redis_client)
28
+ def calls_exceeded_on_query?(rate_limited_field)
29
+ rate_limit = Ratelimit.new(rate_limited_field, redis: redis_client)
22
30
  rate_limit.add(key)
23
- rate_limit.exceeded?(
24
- key,
25
- threshold: threshold,
26
- interval: interval,
27
- )
31
+
32
+ rate_limit.exceeded?(key, threshold: threshold, interval: interval)
28
33
  end
29
34
 
30
35
  def threshold
@@ -44,7 +49,11 @@ module GraphAttack
44
49
  end
45
50
 
46
51
  def redis_client
47
- options[:redis_client] || Redis.current
52
+ options[:redis_client] || Redis.new
53
+ end
54
+
55
+ def rate_limited_key
56
+ options[:on] || :ip
48
57
  end
49
58
  end
50
59
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphAttack
4
- VERSION = '2.0.0'
4
+ VERSION = '2.2.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graph_attack
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fanny Cheung
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-05-05 00:00:00.000000000 Z
12
+ date: 2022-12-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: graphql
@@ -101,42 +101,42 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '1.1'
104
+ version: 1.33.0
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '1.1'
111
+ version: 1.33.0
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: rubocop-rspec
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: '2.2'
118
+ version: 2.12.1
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '2.2'
125
+ version: 2.12.1
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: rubocop-rake
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - ">="
130
+ - - "~>"
131
131
  - !ruby/object:Gem::Version
132
- version: '0'
132
+ version: 0.6.0
133
133
  type: :development
134
134
  prerelease: false
135
135
  version_requirements: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - ">="
137
+ - - "~>"
138
138
  - !ruby/object:Gem::Version
139
- version: '0'
139
+ version: 0.6.0
140
140
  description: GraphQL analyser for blocking & throttling
141
141
  email:
142
142
  - fanny@ynote.hk