graph_attack 2.1.0 → 2.3.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 +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +21 -0
- data/README.md +17 -1
- data/graph_attack.gemspec +1 -1
- data/lib/graph_attack/configuration.rb +37 -0
- data/lib/graph_attack/rate_limit.rb +15 -15
- data/lib/graph_attack/version.rb +1 -1
- data/lib/graph_attack.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5c8d6555e219c82d4a4120f699037145c83a8c6ab5d890aa0f7a75f9560db2c
|
4
|
+
data.tar.gz: da27f205db905e6a6b3c05dd34b50d4057908372c86bae9b53b8f7cb8ef86e09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81506f5a365831038e0fff051d7ef707e4903c561bc8cbbe7148a2ff79daef43ec98e26699331163a42e07328dcd2b08797682155d91b78b54f145809d080dd6
|
7
|
+
data.tar.gz: 964047fc9a4e4516bdb1d6c0ae899e7fdc484c44c83268e9e7dd6fc13ffb563bdba43a4ba6b3a1cecf8ed538c61ec1804eac64fac7418d1094280280d87aeff1
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
unreleased
|
2
2
|
----------
|
3
3
|
|
4
|
+
v2.3.0
|
5
|
+
------
|
6
|
+
|
7
|
+
Feature:
|
8
|
+
- Add configuration for setting defaults. E.g.:
|
9
|
+
|
10
|
+
```rb
|
11
|
+
GraphAttack.configure do |config|
|
12
|
+
# config.threshold = 15
|
13
|
+
# config.interval = 60
|
14
|
+
# config.on = :ip
|
15
|
+
# config.redis_client = Redis.new
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
v2.2.0
|
20
|
+
------
|
21
|
+
|
22
|
+
Feature:
|
23
|
+
- Skip throttling when rate limited field is nil (#19)
|
24
|
+
|
4
25
|
v2.1.0
|
5
26
|
------
|
6
27
|
|
data/README.md
CHANGED
@@ -58,6 +58,8 @@ 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
65
|
### Custom context key
|
@@ -83,6 +85,20 @@ extension GraphAttack::RateLimit,
|
|
83
85
|
redis_client: Redis.new(url: "…")
|
84
86
|
```
|
85
87
|
|
88
|
+
### Common configuration
|
89
|
+
|
90
|
+
To have a default configuration for all rate-limited fields, you can create an
|
91
|
+
initializer:
|
92
|
+
|
93
|
+
```rb
|
94
|
+
GraphAttack.configure do |config|
|
95
|
+
# config.threshold = 15
|
96
|
+
# config.interval = 60
|
97
|
+
# config.on = :ip
|
98
|
+
# config.redis_client = Redis.new
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
86
102
|
## Development
|
87
103
|
|
88
104
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
@@ -102,7 +118,7 @@ tests and linting are pristine by calling `bundle && bin/rake`, then create a
|
|
102
118
|
commit for this version, for example with:
|
103
119
|
|
104
120
|
```sh
|
105
|
-
git add
|
121
|
+
git add --patch
|
106
122
|
git commit -m v`ruby -rbundler/setup -rgraph_attack/version -e "puts GraphAttack::VERSION"`
|
107
123
|
```
|
108
124
|
|
data/graph_attack.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_dependency 'graphql', '>= 1.7.9'
|
30
30
|
|
31
31
|
# A Redis-backed rate limiter.
|
32
|
-
spec.add_dependency 'ratelimit', '>= 1.0.
|
32
|
+
spec.add_dependency 'ratelimit', '>= 1.0.4'
|
33
33
|
|
34
34
|
# Loads local dependencies.
|
35
35
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphAttack
|
4
|
+
# Store the config
|
5
|
+
class Configuration
|
6
|
+
# Number of calls allowed.
|
7
|
+
attr_accessor :threshold
|
8
|
+
|
9
|
+
# Time interval in seconds.
|
10
|
+
attr_accessor :interval
|
11
|
+
|
12
|
+
# Key on the context on which to differentiate users.
|
13
|
+
attr_accessor :on
|
14
|
+
|
15
|
+
# Use a custom Redis client.
|
16
|
+
attr_accessor :redis_client
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@threshold = nil
|
20
|
+
@interval = nil
|
21
|
+
@on = :ip
|
22
|
+
@redis_client = Redis.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
attr_writer :configuration
|
28
|
+
|
29
|
+
def configuration
|
30
|
+
@configuration ||= Configuration.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def configure
|
34
|
+
yield(configuration)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -3,13 +3,13 @@
|
|
3
3
|
module GraphAttack
|
4
4
|
class RateLimit < GraphQL::Schema::FieldExtension
|
5
5
|
def resolve(object:, arguments:, **_rest)
|
6
|
-
rate_limited_field = object.context[
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
rate_limited_field = object.context[on]
|
7
|
+
|
8
|
+
unless object.context.key?(on)
|
9
|
+
raise GraphAttack::Error, "Missing :#{on} key on the GraphQL context"
|
10
10
|
end
|
11
11
|
|
12
|
-
if calls_exceeded_on_query?(rate_limited_field)
|
12
|
+
if rate_limited_field && calls_exceeded_on_query?(rate_limited_field)
|
13
13
|
return RateLimited.new('Query rate limit exceeded')
|
14
14
|
end
|
15
15
|
|
@@ -19,22 +19,21 @@ module GraphAttack
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def key
|
22
|
-
|
23
|
-
|
22
|
+
suffix = "-#{on}" if on != :ip
|
23
|
+
|
24
|
+
"graphql-query-#{field.name}#{suffix}"
|
24
25
|
end
|
25
26
|
|
26
27
|
def calls_exceeded_on_query?(rate_limited_field)
|
27
28
|
rate_limit = Ratelimit.new(rate_limited_field, redis: redis_client)
|
28
29
|
rate_limit.add(key)
|
29
|
-
|
30
|
-
|
31
|
-
threshold: threshold,
|
32
|
-
interval: interval,
|
33
|
-
)
|
30
|
+
|
31
|
+
rate_limit.exceeded?(key, threshold: threshold, interval: interval)
|
34
32
|
end
|
35
33
|
|
36
34
|
def threshold
|
37
35
|
options[:threshold] ||
|
36
|
+
GraphAttack.configuration.threshold ||
|
38
37
|
raise(
|
39
38
|
GraphAttack::Error,
|
40
39
|
'Missing "threshold:" option on the GraphAttack::RateLimit extension',
|
@@ -43,6 +42,7 @@ module GraphAttack
|
|
43
42
|
|
44
43
|
def interval
|
45
44
|
options[:interval] ||
|
45
|
+
GraphAttack.configuration.interval ||
|
46
46
|
raise(
|
47
47
|
GraphAttack::Error,
|
48
48
|
'Missing "interval:" option on the GraphAttack::RateLimit extension',
|
@@ -50,11 +50,11 @@ module GraphAttack
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def redis_client
|
53
|
-
options[:redis_client] ||
|
53
|
+
options[:redis_client] || GraphAttack.configuration.redis_client
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
57
|
-
options[:on] ||
|
56
|
+
def on
|
57
|
+
options[:on] || GraphAttack.configuration.on
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
data/lib/graph_attack/version.rb
CHANGED
data/lib/graph_attack.rb
CHANGED
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.
|
4
|
+
version: 2.3.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:
|
12
|
+
date: 2023-02-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: graphql
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 1.0.
|
34
|
+
version: 1.0.4
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 1.0.
|
41
|
+
version: 1.0.4
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: bundler
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +164,7 @@ files:
|
|
164
164
|
- bin/setup
|
165
165
|
- graph_attack.gemspec
|
166
166
|
- lib/graph_attack.rb
|
167
|
+
- lib/graph_attack/configuration.rb
|
167
168
|
- lib/graph_attack/error.rb
|
168
169
|
- lib/graph_attack/rate_limit.rb
|
169
170
|
- lib/graph_attack/rate_limited.rb
|