graph_attack 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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