strait 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +18 -0
- data/.github/workflows/release.yml +39 -0
- data/.github/workflows/test.yml +51 -0
- data/Gemfile.lock +28 -26
- data/LICENSE.txt +1 -12
- data/README.md +12 -9
- data/lib/strait/version.rb +1 -1
- data/lib/strait.rb +3 -3
- data/strait.gemspec +3 -3
- metadata +10 -7
- data/.travis.yml +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 459f330c3b15b42c2cd218e7bc60f4e1579288f60bb7e2cd6b286a970323f44d
|
4
|
+
data.tar.gz: 518f4012eeaa1170e0feddd5797f1b7777e47a0b0b64e5cd189978d14aa1c6ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4185c8ad2907a75bc3577287193d35c5c7f35216d2ddd6c3e8a0d1e4063d2de043d735a38dc5f0d4134adf4fe0759311e3dbadf2bd5749be3d0e47b5a6692fb2
|
7
|
+
data.tar.gz: 21e760fc2801ffacff6a67f342ff7e0f204f4820c07503f0f9d830c2397b47b35c50427b2f4b0d4c2b3aef57029eb58fcb991cc852c7e58c9a4cdd22a5011fae
|
@@ -0,0 +1,18 @@
|
|
1
|
+
version: 2
|
2
|
+
updates:
|
3
|
+
- package-ecosystem: bundler
|
4
|
+
directory: "/"
|
5
|
+
schedule:
|
6
|
+
interval: daily
|
7
|
+
time: "17:00"
|
8
|
+
timezone: America/Los_Angeles
|
9
|
+
open-pull-requests-limit: 10
|
10
|
+
reviewers:
|
11
|
+
- NuckChorris
|
12
|
+
ignore:
|
13
|
+
- dependency-name: connection_pool
|
14
|
+
versions:
|
15
|
+
- 2.2.4
|
16
|
+
- dependency-name: timecop
|
17
|
+
versions:
|
18
|
+
- 0.9.3
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: Release to rubygems
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
paths:
|
8
|
+
- "lib/strait/version.rb"
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
release:
|
12
|
+
name: Relase to Rubygems
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- name: Checkout Repository
|
17
|
+
uses: actions/checkout@v1
|
18
|
+
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: 3.0
|
23
|
+
bundler-cache: true
|
24
|
+
|
25
|
+
- name: Authenticate with Rubygems
|
26
|
+
run: |
|
27
|
+
mkdir -p $HOME/.gem/
|
28
|
+
echo "${RUBYGEMS_CREDENTIALS}" > $HOME/.gem/credentials
|
29
|
+
chmod 0600 $HOME/.gem/credentials
|
30
|
+
env:
|
31
|
+
RUBYGEMS_CREDENTIALS: ${{ secrets.SENKO_SAN_RUBYGEMS_CREDENTIALS }}
|
32
|
+
|
33
|
+
- name: Publish Gem on Rubygems
|
34
|
+
run: bundle exec rake release:rubygem_push
|
35
|
+
|
36
|
+
- name: Create a Github Release
|
37
|
+
run: gh release create $(ruby -r './lib/strait/version' -e "puts Strait::VERSION") --target "${GITHUB_SHA}"
|
38
|
+
env:
|
39
|
+
GITHUB_TOKEN: ${{ secrets.SENKO_SAN_KEY }}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
name: Strait Test Suite
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
pull_request:
|
6
|
+
# Branches from forks have the form 'user:branch-name' so we only run
|
7
|
+
# this job on pull_request events for branches that look like fork
|
8
|
+
# branches. Without this we would end up running this job twice for non
|
9
|
+
# forked PRs, once for the push and then once for opening the PR.
|
10
|
+
branches:
|
11
|
+
- "**:**"
|
12
|
+
|
13
|
+
env:
|
14
|
+
CC_TEST_REPORTER_ID: 1f7851d1df80cc24da6903abf795ee7a81a60b2cceb7eedd147c59c4ec232dd4
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
name: RSpec Test Suite
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
continue-on-error: ${{ matrix.experimental }}
|
21
|
+
strategy:
|
22
|
+
fail-fast: false
|
23
|
+
matrix:
|
24
|
+
ruby:
|
25
|
+
- ruby-2.6
|
26
|
+
- ruby-2.7
|
27
|
+
experimental: [false]
|
28
|
+
include:
|
29
|
+
- ruby: truffleruby-20
|
30
|
+
experimental: true
|
31
|
+
- ruby: ruby-3.0
|
32
|
+
experimental: true
|
33
|
+
- ruby: ruby-3.1
|
34
|
+
experimental: true
|
35
|
+
|
36
|
+
steps:
|
37
|
+
- name: Checkout Repository
|
38
|
+
uses: actions/checkout@v1
|
39
|
+
|
40
|
+
- name: Set up Ruby (${{ matrix.ruby }})
|
41
|
+
uses: ruby/setup-ruby@v1
|
42
|
+
with:
|
43
|
+
ruby-version: ${{ matrix.ruby }}
|
44
|
+
bundler-cache: true
|
45
|
+
|
46
|
+
- name: Run Tests
|
47
|
+
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
|
48
|
+
run: bundle exec rspec
|
49
|
+
|
50
|
+
- name: Publish code coverage
|
51
|
+
uses: paambaati/codeclimate-action@v3.0.0
|
data/Gemfile.lock
CHANGED
@@ -1,39 +1,41 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
strait (1.
|
4
|
+
strait (1.2.0)
|
5
5
|
connection_pool (>= 2.0, < 3.0)
|
6
6
|
redis (~> 4.0, >= 3.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
connection_pool (2.2.
|
12
|
-
diff-lcs (1.
|
13
|
-
docile (1.
|
14
|
-
|
15
|
-
|
16
|
-
rake (
|
17
|
-
redis (4.
|
18
|
-
rspec (3.
|
19
|
-
rspec-core (~> 3.
|
20
|
-
rspec-expectations (~> 3.
|
21
|
-
rspec-mocks (~> 3.
|
22
|
-
rspec-core (3.
|
23
|
-
rspec-support (~> 3.
|
24
|
-
rspec-expectations (3.
|
11
|
+
connection_pool (2.2.5)
|
12
|
+
diff-lcs (1.5.0)
|
13
|
+
docile (1.4.0)
|
14
|
+
mock_redis (0.31.0)
|
15
|
+
ruby2_keywords
|
16
|
+
rake (13.0.6)
|
17
|
+
redis (4.6.0)
|
18
|
+
rspec (3.11.0)
|
19
|
+
rspec-core (~> 3.11.0)
|
20
|
+
rspec-expectations (~> 3.11.0)
|
21
|
+
rspec-mocks (~> 3.11.0)
|
22
|
+
rspec-core (3.11.0)
|
23
|
+
rspec-support (~> 3.11.0)
|
24
|
+
rspec-expectations (3.11.0)
|
25
25
|
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
-
rspec-support (~> 3.
|
27
|
-
rspec-mocks (3.
|
26
|
+
rspec-support (~> 3.11.0)
|
27
|
+
rspec-mocks (3.11.1)
|
28
28
|
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
-
rspec-support (~> 3.
|
30
|
-
rspec-support (3.
|
31
|
-
|
29
|
+
rspec-support (~> 3.11.0)
|
30
|
+
rspec-support (3.11.0)
|
31
|
+
ruby2_keywords (0.0.5)
|
32
|
+
simplecov (0.21.2)
|
32
33
|
docile (~> 1.1)
|
33
|
-
|
34
|
-
|
35
|
-
simplecov-html (0.
|
36
|
-
|
34
|
+
simplecov-html (~> 0.11)
|
35
|
+
simplecov_json_formatter (~> 0.1)
|
36
|
+
simplecov-html (0.12.3)
|
37
|
+
simplecov_json_formatter (0.1.4)
|
38
|
+
timecop (0.9.5)
|
37
39
|
|
38
40
|
PLATFORMS
|
39
41
|
ruby
|
@@ -41,11 +43,11 @@ PLATFORMS
|
|
41
43
|
DEPENDENCIES
|
42
44
|
bundler (~> 2.0)
|
43
45
|
mock_redis (~> 0.21)
|
44
|
-
rake (~>
|
46
|
+
rake (~> 13.0)
|
45
47
|
rspec (~> 3.0)
|
46
48
|
simplecov (~> 0.17)
|
47
49
|
strait!
|
48
50
|
timecop (~> 0.9)
|
49
51
|
|
50
52
|
BUNDLED WITH
|
51
|
-
2.
|
53
|
+
2.3.13
|
data/LICENSE.txt
CHANGED
@@ -175,18 +175,7 @@
|
|
175
175
|
|
176
176
|
END OF TERMS AND CONDITIONS
|
177
177
|
|
178
|
-
|
179
|
-
|
180
|
-
To apply the Apache License to your work, attach the following
|
181
|
-
boilerplate notice, with the fields enclosed by brackets "[]"
|
182
|
-
replaced with your own identifying information. (Don't include
|
183
|
-
the brackets!) The text should be enclosed in the appropriate
|
184
|
-
comment syntax for the file format. We also recommend that a
|
185
|
-
file or class name and description of purpose be included on the
|
186
|
-
same "printed page" as the copyright notice for easier
|
187
|
-
identification within third-party archives.
|
188
|
-
|
189
|
-
Copyright 2019 Kitsu, Inc.
|
178
|
+
Copyright 2021 Kitsu, Inc.
|
190
179
|
|
191
180
|
Licensed under the Apache License, Version 2.0 (the "License");
|
192
181
|
you may not use this file except in compliance with the License.
|
data/README.md
CHANGED
@@ -2,16 +2,19 @@
|
|
2
2
|
|
3
3
|
[![Coverage][shield-coverage]][coverage]
|
4
4
|
[![Maintainability][shield-maintainability]][maintainability]
|
5
|
-
[![
|
5
|
+
[![Github Actions][shield-actions]][actions]
|
6
|
+
[![Rubygem Version][shield-version]][version]
|
6
7
|
|
7
8
|
[shield-coverage]: https://img.shields.io/codeclimate/coverage/hummingbird-me/strait.svg?logo=code-climate&style=for-the-badge
|
8
9
|
[coverage]: https://codeclimate.com/github/hummingbird-me/strait/progress/coverage
|
9
10
|
[shield-maintainability]: https://img.shields.io/codeclimate/maintainability/hummingbird-me/strait.svg?logo=code-climate&style=for-the-badge
|
10
11
|
[maintainability]: https://codeclimate.com/github/hummingbird-me/strait/progress/maintainability
|
11
|
-
[shield-
|
12
|
-
[
|
12
|
+
[shield-actions]: https://img.shields.io/github/checks-status/hummingbird-me/strait/main?style=for-the-badge
|
13
|
+
[actions]: https://github.com/hummingbird-me/strait/actions
|
14
|
+
[shield-version]: https://img.shields.io/gem/v/strait?label=%20&logo=rubygems&logoColor=white&style=for-the-badge
|
15
|
+
[version]: https://rubygems.org/gems/strait
|
13
16
|
|
14
|
-
Strait is a rate-limiting library designed to provide security you don't need to think about.
|
17
|
+
Strait is a rate-limiting library designed to provide security you don't need to think about. Whenever you have code to protect, put a Strait in front of it.
|
15
18
|
|
16
19
|
It strikes an excellent balance between accuracy and memory usage, with a default accuracy of 1/60th of the limit period.
|
17
20
|
|
@@ -43,7 +46,7 @@ class SecureThingController
|
|
43
46
|
end
|
44
47
|
```
|
45
48
|
|
46
|
-
Well dang, that's no good.
|
49
|
+
Well dang, that's no good. Anybody could send thousands of requests to this and take your entire site down, right as you're meeting with an important investor!
|
47
50
|
|
48
51
|
Let's put a Strait in front of it!
|
49
52
|
|
@@ -64,15 +67,15 @@ class SecureThingController
|
|
64
67
|
end
|
65
68
|
```
|
66
69
|
|
67
|
-
Viola, just like that, we've got rate limiting.
|
70
|
+
Viola, just like that, we've got rate limiting. Now a user is limited to 5 per minute!
|
68
71
|
|
69
72
|
## Accuracy
|
70
73
|
|
71
|
-
To understand why Strait isn't perfectly accurate, we should understand how it's implemented.
|
74
|
+
To understand why Strait isn't perfectly accurate, we should understand how it's implemented. Strait is based on [the bucketed-log pattern made popular by Figma][figma-post], which chooses lower memory usage over perfect accuracy. Despite this decreased accuracy, it fails secure, and should have enough accuracy to not be noticed.
|
72
75
|
|
73
|
-
Each rate limiter stores data as a set of _N buckets per period_.
|
76
|
+
Each rate limiter stores data as a set of _N buckets per period_. For example, with 10 buckets and a 1-hour period, each bucket covers 6 minutes. To check the limit, we sum all buckets which overlap the last hour. If the buckets are large (like 6 minutes) this can be up to one bucket longer than the period, resulting in a longer block than 100% accuracy.
|
74
77
|
|
75
|
-
The default accuracy in Strait is _60 buckets per period_.
|
78
|
+
The default accuracy in Strait is _60 buckets per period_. For a 1-hour period, this is up to 1 minute of inaccuracy. For a 1-minute period, it's up to 1-second. For a 1-day period, it's up to 24 minutes. You can adjust this to increase accuracy, but it will also use more memory.
|
76
79
|
|
77
80
|
[figma-post]: https://www.figma.com/blog/an-alternative-approach-to-rate-limiting/
|
78
81
|
|
data/lib/strait/version.rb
CHANGED
data/lib/strait.rb
CHANGED
@@ -10,12 +10,12 @@ require 'strait/version'
|
|
10
10
|
class Strait
|
11
11
|
attr_reader :name, :config
|
12
12
|
|
13
|
-
def initialize(name, rules: [], **config)
|
13
|
+
def initialize(name, rules: [], **config, &block)
|
14
14
|
@name = name
|
15
15
|
@raw_rules = rules
|
16
16
|
@config = Strait::Configuration.default.merge(config)
|
17
17
|
|
18
|
-
@raw_rules += Strait::DSL.new(&
|
18
|
+
@raw_rules += Strait::DSL.new(&block).rules unless block.nil?
|
19
19
|
end
|
20
20
|
|
21
21
|
def limit!(user)
|
@@ -26,7 +26,7 @@ class Strait
|
|
26
26
|
|
27
27
|
# Raise an exception for the first rate limit hit
|
28
28
|
results.each do |rule, acceptable|
|
29
|
-
raise Strait::RateLimitExceeded
|
29
|
+
raise Strait::RateLimitExceeded.new(**rule.to_h) unless acceptable
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
data/strait.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['Emma Lejeck']
|
9
9
|
spec.email = ['nuck@kitsu.io']
|
10
10
|
|
11
|
-
spec.summary = 'Rate-limiting to defend your nation-state'
|
11
|
+
spec.summary = 'Rate-limiting to defend your nation-state from pillagers'
|
12
12
|
spec.description = <<~DESC
|
13
13
|
Strait is a rate-limiting library designed to provide security you don't need to think about.
|
14
14
|
Whenever you have code to protect, put a Strait in front of it.
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
|
19
19
|
spec.metadata['homepage_uri'] = spec.homepage
|
20
20
|
spec.metadata['source_code_uri'] = 'https://github.com/hummingbird-me/strait'
|
21
|
-
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/hummingbird-me/strait/releases"
|
22
22
|
|
23
23
|
# Specify which files should be added to the gem when it is released.
|
24
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
33
33
|
spec.add_development_dependency 'mock_redis', '~> 0.21'
|
34
|
-
spec.add_development_dependency 'rake', '~>
|
34
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
35
35
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
36
36
|
spec.add_development_dependency 'simplecov', '~> 0.17'
|
37
37
|
spec.add_development_dependency 'timecop', '~> 0.9'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strait
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emma Lejeck
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,10 +144,12 @@ extensions: []
|
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
146
|
- ".editorconfig"
|
147
|
+
- ".github/dependabot.yml"
|
148
|
+
- ".github/workflows/release.yml"
|
149
|
+
- ".github/workflows/test.yml"
|
147
150
|
- ".gitignore"
|
148
151
|
- ".rspec"
|
149
152
|
- ".rubocop.yml"
|
150
|
-
- ".travis.yml"
|
151
153
|
- Gemfile
|
152
154
|
- Gemfile.lock
|
153
155
|
- LICENSE.txt
|
@@ -168,6 +170,7 @@ licenses:
|
|
168
170
|
metadata:
|
169
171
|
homepage_uri: https://github.com/hummingbird-me/strait
|
170
172
|
source_code_uri: https://github.com/hummingbird-me/strait
|
173
|
+
changelog_uri: https://github.com/hummingbird-me/strait/releases
|
171
174
|
post_install_message:
|
172
175
|
rdoc_options: []
|
173
176
|
require_paths:
|
@@ -183,8 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
186
|
- !ruby/object:Gem::Version
|
184
187
|
version: '0'
|
185
188
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
189
|
+
rubygems_version: 3.3.7
|
187
190
|
signing_key:
|
188
191
|
specification_version: 4
|
189
|
-
summary: Rate-limiting to defend your nation-state
|
192
|
+
summary: Rate-limiting to defend your nation-state from pillagers
|
190
193
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sudo: false
|
3
|
-
language: ruby
|
4
|
-
cache: bundler
|
5
|
-
rvm:
|
6
|
-
- 2.6.3
|
7
|
-
env:
|
8
|
-
global:
|
9
|
-
- CC_TEST_REPORTER_ID=1f7851d1df80cc24da6903abf795ee7a81a60b2cceb7eedd147c59c4ec232dd4
|
10
|
-
|
11
|
-
before_install: gem install bundler -v 2.0.2
|
12
|
-
before_script:
|
13
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
14
|
-
- chmod +x ./cc-test-reporter
|
15
|
-
- ./cc-test-reporter before-build
|
16
|
-
script:
|
17
|
-
- bundle exec rspec
|
18
|
-
after_script:
|
19
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|