action_ip_filter 0.4.1 → 0.5.1
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/CHANGELOG.md +10 -0
- data/README.md +34 -13
- data/lib/action_ip_filter/configuration.rb +17 -2
- data/lib/action_ip_filter/ip_filterable.rb +6 -5
- data/lib/action_ip_filter/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89a56e3e93ef8dd25c9aae21185810b83cdf6c27662db6ba5749ee8ccc12976e
|
|
4
|
+
data.tar.gz: 674e5ce2970c6fe3e91469d856b6052a2eaa26e4a83ada61d5214f4ad49df7e9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: badbaf5b413e15360b998db3aa662233219a5de020a588e06912aae2abc487fd45059aeb91445afe0a33c1b25b0886b0486ba7866346488d295835f78a42e2e5
|
|
7
|
+
data.tar.gz: 51194a577f7885a3a63e48acb10210bd3b4ad8b33d059449a3525d22b7ca25d5b8d6a8bdf0132bfb7163872b436ac9054459c2ba8b8c30409b6b5fbc65e70eff
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.5.1] - 2025-12-15
|
|
4
|
+
|
|
5
|
+
There are no changes in core logic. Only the release toolchain has been changed.
|
|
6
|
+
|
|
7
|
+
## [0.5.0] - 2025-12-02
|
|
8
|
+
|
|
9
|
+
### New Features
|
|
10
|
+
|
|
11
|
+
- Make `log_denial_message` configurable [#9](https://github.com/smartbank-inc/action_ip_filter/pull/9)
|
|
12
|
+
|
|
3
13
|
## [0.4.1] - 2025-12-01
|
|
4
14
|
|
|
5
15
|
### Bug Fix
|
data/README.md
CHANGED
|
@@ -6,12 +6,12 @@ A lightweight gem that provides IP address restrictions for Rails controllers at
|
|
|
6
6
|
|
|
7
7
|
Unlike Rack middleware solutions (e.g., `rack-attack`), action_ip_filter operates at the controller level:
|
|
8
8
|
|
|
9
|
-
| Feature
|
|
10
|
-
|
|
11
|
-
| Layer
|
|
12
|
-
| Granularity | Path/IP based
|
|
13
|
-
| Overhead
|
|
14
|
-
| Use case
|
|
9
|
+
| Feature | rack-attack | action_ip_filter |
|
|
10
|
+
|-------------|--------------------------------|--------------------------|
|
|
11
|
+
| Layer | Rack middleware (all requests) | Controller before_action |
|
|
12
|
+
| Granularity | Path/IP based | Controller/Action based |
|
|
13
|
+
| Overhead | Every request evaluated | Only specified actions |
|
|
14
|
+
| Use case | DDoS protection, rate limiting | Admin panels, webhooks |
|
|
15
15
|
|
|
16
16
|
**Use this gem when you need:**
|
|
17
17
|
- IP restrictions on specific controller actions only
|
|
@@ -177,17 +177,36 @@ ActionIpFilter.configure do |config|
|
|
|
177
177
|
|
|
178
178
|
# Enable/disable denial logging (default: true)
|
|
179
179
|
config.log_denials = true
|
|
180
|
+
|
|
181
|
+
# Logging on denied
|
|
182
|
+
# It passes `config.logger` as the first argument (logger) and the actual client IP address as the second argument (client_ip).
|
|
183
|
+
config.log_denial_message = ->(logger, client_ip) {
|
|
184
|
+
logger.error("Blocked IP: #{client_ip}")
|
|
185
|
+
}
|
|
180
186
|
end
|
|
181
187
|
```
|
|
182
188
|
|
|
183
189
|
### Default Values
|
|
184
190
|
|
|
185
|
-
| Option
|
|
186
|
-
|
|
187
|
-
| `ip_resolver`
|
|
188
|
-
| `on_denied`
|
|
189
|
-
| `logger`
|
|
190
|
-
| `log_denials`
|
|
191
|
+
| Option | Default | Description |
|
|
192
|
+
|----------------------|----------------------------|----------------------------------------------------|
|
|
193
|
+
| `ip_resolver` | `-> { request.remote_ip }` | Proc that extracts client IP from request |
|
|
194
|
+
| `on_denied` | `-> { head :forbidden }` | Handler called when access is denied (returns 403) |
|
|
195
|
+
| `logger` | `Rails.logger` | Logger instance for denied request logging |
|
|
196
|
+
| `log_denials` | `true` | Whether to log denied requests as warn level |
|
|
197
|
+
| `log_denial_message` | See below | Proc that formats the denial log message |
|
|
198
|
+
|
|
199
|
+
The default `log_denial_message` is:
|
|
200
|
+
|
|
201
|
+
```ruby
|
|
202
|
+
->(logger, client_ip) {
|
|
203
|
+
logger.warn("[ActionIpFilter] Access denied for IP: #{client_ip} on #{self.class.name}##{action_name}")
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Note on the configurable Proc block
|
|
208
|
+
|
|
209
|
+
The block is executed via `instance_exec` in the controller context, so you may call controller methods such as `request`, `head`, `render`, and others.
|
|
191
210
|
|
|
192
211
|
## Testing
|
|
193
212
|
|
|
@@ -240,12 +259,14 @@ end
|
|
|
240
259
|
|
|
241
260
|
## Logging
|
|
242
261
|
|
|
243
|
-
When `log_denials` is enabled
|
|
262
|
+
When `log_denials` is enabled, denied requests are logged as default:
|
|
244
263
|
|
|
245
264
|
```
|
|
246
265
|
[ActionIpFilter] Access denied for IP: 192.0.2.1 on MyController#index
|
|
247
266
|
```
|
|
248
267
|
|
|
268
|
+
See also: the `log_denial_message` configuration, which allows you to adjust both the log level and the message.
|
|
269
|
+
|
|
249
270
|
## Development
|
|
250
271
|
|
|
251
272
|
```bash
|
|
@@ -6,18 +6,33 @@ module ActionIpFilter
|
|
|
6
6
|
# @rbs @on_denied: ^() -> void
|
|
7
7
|
# @rbs @logger: Logger?
|
|
8
8
|
# @rbs @log_denials: bool
|
|
9
|
+
# @rbs @log_denial_message: ^(Logger, String?) -> void
|
|
10
|
+
|
|
11
|
+
# @rbs!
|
|
12
|
+
# interface _Request
|
|
13
|
+
# def remote_ip: () -> String
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# def action_name: () -> String
|
|
17
|
+
# def controller_name: () -> String
|
|
18
|
+
# def head: (Symbol) -> void
|
|
19
|
+
# def request: () -> _Request
|
|
9
20
|
|
|
10
21
|
attr_accessor :ip_resolver #: ^() -> String?
|
|
11
22
|
attr_accessor :on_denied #: ^() -> void
|
|
12
23
|
attr_accessor :logger #: Logger?
|
|
13
24
|
attr_accessor :log_denials #: bool
|
|
25
|
+
attr_accessor :log_denial_message #: ^(Logger, String?) -> void
|
|
14
26
|
|
|
15
27
|
# @rbs return: void
|
|
16
28
|
def initialize
|
|
17
|
-
@ip_resolver = -> { request.remote_ip }
|
|
18
|
-
@on_denied = -> { head :forbidden }
|
|
29
|
+
@ip_resolver = -> { request.remote_ip }
|
|
30
|
+
@on_denied = -> { head :forbidden }
|
|
19
31
|
@logger = nil
|
|
20
32
|
@log_denials = true
|
|
33
|
+
@log_denial_message = ->(logger, client_ip) {
|
|
34
|
+
logger.warn("[ActionIpFilter] Access denied for IP: #{client_ip} on #{self.class.name}##{action_name}")
|
|
35
|
+
}
|
|
21
36
|
end
|
|
22
37
|
end
|
|
23
38
|
|
|
@@ -7,8 +7,8 @@ module ActionIpFilter
|
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
9
9
|
# @rbs!
|
|
10
|
-
# def
|
|
11
|
-
#
|
|
10
|
+
# def instance_exec: [T] () { () -> T } -> T
|
|
11
|
+
# | (Logger, String?) { (Logger, String?) -> void } -> void
|
|
12
12
|
# def before_action: (*untyped, **untyped) -> void
|
|
13
13
|
|
|
14
14
|
class_methods do
|
|
@@ -57,9 +57,10 @@ module ActionIpFilter
|
|
|
57
57
|
logger = ActionIpFilter.configuration.logger
|
|
58
58
|
return if logger.nil?
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
log_denial_message = ActionIpFilter.configuration.log_denial_message
|
|
61
|
+
return if log_denial_message.nil?
|
|
62
|
+
|
|
63
|
+
instance_exec(logger, client_ip, &log_denial_message)
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
end
|