-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
93 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# frozen_string_literal: true | ||
|
||
# A limiter is a specialized form of a counter that can be checked whether it has been exceeded and is provided fail safe. This means it can be used to guard login screens from brute force attacks without denying access in case Redis is offline. | ||
# | ||
# It will usually be used as an expiring limiter. Note that the limiter expires in total after the `expires_in` time used upon the first poke. | ||
# | ||
# It offers no guarentee that you can't poke yourself above the limit. You're responsible for checking `#exceeded?` yourself first, and this may produce a race condition. So only use this when the exact number of pokes is not critical. | ||
class Kredis::Types::Limiter < Kredis::Types::Counter | ||
class LimitExceeded < StandardError; end | ||
|
||
attr_accessor :limit | ||
|
||
def poke | ||
failsafe returning: true do | ||
increment | ||
end | ||
end | ||
|
||
def exceeded? | ||
failsafe returning: false do | ||
value >= limit | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
class LimiterTest < ActiveSupport::TestCase | ||
setup { @limiter = Kredis.limiter "mylimit", limit: 5 } | ||
|
||
test "exceeded after limit is reached" do | ||
4.times do | ||
@limiter.poke | ||
assert_not @limiter.exceeded? | ||
end | ||
|
||
@limiter.poke | ||
assert @limiter.exceeded? | ||
end | ||
|
||
test "never exceeded when redis is down" do | ||
stub_redis_down(@limiter) do | ||
10.times do | ||
@limiter.poke | ||
assert_not @limiter.exceeded? | ||
end | ||
end | ||
end | ||
end |