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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de17498105231eb4dd5b5135cf8e7683680cafc409a66acf6fddbaa6f6735b36
4
- data.tar.gz: 60308e8ccff6fb80b4b5013975f9ea4903cb037b16997030635ace4557211f17
3
+ metadata.gz: e5c8d6555e219c82d4a4120f699037145c83a8c6ab5d890aa0f7a75f9560db2c
4
+ data.tar.gz: da27f205db905e6a6b3c05dd34b50d4057908372c86bae9b53b8f7cb8ef86e09
5
5
  SHA512:
6
- metadata.gz: 41706b8ea7768bf2d3220c6803f91c29a20640b177c8c443cf64a3462310dd939d4dfa92ffd2fd9f874bd6f256e50031ffbf893f5f4a58846fd7299191e12169
7
- data.tar.gz: 873abb6b86cb16f3575cff878cd2be3d0c47723b472b2949a6f4c0f9c6164996fa3b72142ce3e74a71952c5da89eac400a346a43607f174fa2e28862c5dd8d57
6
+ metadata.gz: 81506f5a365831038e0fff051d7ef707e4903c561bc8cbbe7148a2ff79daef43ec98e26699331163a42e07328dcd2b08797682155d91b78b54f145809d080dd6
7
+ data.tar.gz: 964047fc9a4e4516bdb1d6c0ae899e7fdc484c44c83268e9e7dd6fc13ffb563bdba43a4ba6b3a1cecf8ed538c61ec1804eac64fac7418d1094280280d87aeff1
data/.rubocop.yml CHANGED
@@ -69,7 +69,7 @@ RSpec/NestedGroups:
69
69
 
70
70
  # Allow longer examples (default 5)
71
71
  RSpec/ExampleLength:
72
- Max: 8
72
+ Max: 15
73
73
 
74
74
  Layout/EmptyLinesAroundAttributeAccessor:
75
75
  Enabled: true
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.3'
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[rate_limited_key]
7
- unless rate_limited_field
8
- raise GraphAttack::Error,
9
- "Missing :#{rate_limited_key} value on the GraphQL context"
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
- on = "-#{options[:on]}" if options[:on]
23
- "graphql-query-#{field.name}#{on}"
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
- rate_limit.exceeded?(
30
- key,
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] || Redis.current
53
+ options[:redis_client] || GraphAttack.configuration.redis_client
54
54
  end
55
55
 
56
- def rate_limited_key
57
- options[:on] || :ip
56
+ def on
57
+ options[:on] || GraphAttack.configuration.on
58
58
  end
59
59
  end
60
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphAttack
4
- VERSION = '2.1.0'
4
+ VERSION = '2.3.0'
5
5
  end
data/lib/graph_attack.rb CHANGED
@@ -6,7 +6,7 @@ require 'graphql/tracing'
6
6
 
7
7
  require 'graph_attack/version'
8
8
 
9
- # Class-based schema
9
+ require 'graph_attack/configuration'
10
10
  require 'graph_attack/error'
11
11
  require 'graph_attack/rate_limit'
12
12
  require 'graph_attack/rate_limited'
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.1.0
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: 2022-08-07 00:00:00.000000000 Z
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.3
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.3
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