decidim-cdtb 0.5.4 → 0.5.6

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: 503b64bc8fc2ef3f45edcdabff3591d23a075cfb48e25cb624f061e7019f0f03
4
- data.tar.gz: 3574d5efd2e3d9f08e510f24df8f8c92ec9f45e3efea1e1308afc1ebcb58465d
3
+ metadata.gz: 303e4725f5b7dde9f45b5bb2c866d3cbdb118ef35f81effbd47b58767a0c1657
4
+ data.tar.gz: b95307923329f47530efe27d6cb77f8b9009e6a5ce70b575771116ef87e4a195
5
5
  SHA512:
6
- metadata.gz: 37affa74d1f8761a42c1a6e64ecf93cbd9422208e169dc318d765b3fb650bdfc056fcf4a3a00ef2b1d95103ace679815e0fc933d5ebbda2447f3d47ba94f7902
7
- data.tar.gz: ece1b559779d9a45d378afb760f4df73aeca4866ef94c6b6561b599d9dfaf4db2033b2c7e674226e6753cd662728cc6db931389f19cbae3c8973a947701fa9ff
6
+ metadata.gz: fb14724b3a4cf851bddeebb2404bd2473b740feda827ffb9a1ac15a2b3abe9826211b06aa95bcdede13b52d7fb12d542eaf4deac6c13143c044562dc259b4e11
7
+ data.tar.gz: 38da29e0a9190ae671923376168c4f45719fc3c8feb5ecf306a420485222d26da217ddfd63712eb6363bb12c22fd8a39e1cf199c64d63f1ca032f04e12992f75
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.6] - 2025-08-11 (minor - Escola de monstres, gràcies!)
4
+
5
+ - Wrap RackAttack IP related parsing into IpParser.
6
+ - Allow to extend Rack::Request.ip_filter regex used internally by Rack::Request.trusted_proxy?(ip).
7
+
8
+ ## [0.5.5] - 2025-08-03 (patch - Esquelètic pero frenètic)
9
+
10
+ - Fix params in Users::Remover task
11
+
3
12
  ## [0.5.4] - 2025-07-10 (patch - Una festa que no resta)
4
13
 
5
14
  - Use `main` as default git branch in CI generators
data/Gemfile.lock CHANGED
@@ -141,7 +141,7 @@ GIT
141
141
  PATH
142
142
  remote: .
143
143
  specs:
144
- decidim-cdtb (0.5.4)
144
+ decidim-cdtb (0.5.6)
145
145
  decidim (>= 0.28.0)
146
146
  rails (>= 6)
147
147
  ruby-progressbar
data/README.md CHANGED
@@ -67,6 +67,18 @@ Fixes YouTube embeds to Decidim v0.28 format in different places, which at the m
67
67
  bin/rake cdtb:embeds:fix_youtube
68
68
  ```
69
69
 
70
+ ### Logging
71
+
72
+ #### IP logging
73
+
74
+ See `config/initializers/ip_filtering.rb` to learn how to add conditions to `Rack::Request.trusted_proxy?(ip)`.
75
+
76
+ Example, to add your 10.2.0.4 proxy as a trusted proxy define the following ENV var:
77
+
78
+ ```
79
+ # don't forget the OR at the beginnig
80
+ RACK_RQ_IP_FILTER_EXT="|\A10\.2\.0\.4\Z"
81
+ ```
70
82
 
71
83
  ### Migrate ActiveStorage service from S3 to local
72
84
 
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cdtb/ip_parser"
4
+
5
+ unless ENV["CDTB_RACK_ATTACK_DISABLED"].to_i.positive? || %w[development test].include?(Rails.env)
6
+ require "rack/attack"
7
+ Cdtb::IpParser.decorate_rack_request
8
+
9
+ limit= ENV.fetch("RACK_ATTACK_THROTTLE_LIMIT", 30)
10
+ period= ENV.fetch("RACK_ATTACK_THROTTLE_PERIOD", 60)
11
+ Rails.logger.info("Configuring Rack::Attack.throttle with limit for requests by ip: #{limit}, period: #{period}")
12
+ Rack::Attack.throttle("cdtb:requests by ip", limit: limit.to_i, period: period.to_i) do |request|
13
+ # ignore requests to assets
14
+ next if request.path.start_with?("/rails/active_storage")
15
+
16
+ Cdtb::IpParser.extract_ip(request)
17
+ end
18
+
19
+ if ENV.key?("RACK_ATTACK_THROTTLE_RANGE_LIMIT") && ENV["RACK_ATTACK_THROTTLE_RANGE_LIMIT"].to_i.positive?
20
+ limit= ENV.fetch("RACK_ATTACK_THROTTLE_RANGE_LIMIT", 30)
21
+ period= ENV.fetch("RACK_ATTACK_THROTTLE_RANGE_PERIOD", 60)
22
+ Rails.logger.info("Configuring Rack::Attack.throttle with limit for IP Ranges: #{limit}, period: #{period}")
23
+ Rack::Attack.throttle("cdtb:requests by ip range", limit: limit.to_i, period: period.to_i) do |request|
24
+ # ignore requests to assets
25
+ next if request.path.start_with?("/rails/active_storage")
26
+
27
+ ip= Cdtb::IpParser.extract_ip(request)
28
+ # rubocop: disable Lint/UselessAssignment
29
+ range_32bit= ip.split(".")[0, 2]
30
+ # rubocop: enable Lint/UselessAssignment
31
+ end
32
+ end
33
+
34
+ Rack::Attack.blocklist("cdtb:block all /.well-known/traffic-advice") do |request|
35
+ request.path.start_with?("/.well-known/traffic-advice")
36
+ end
37
+
38
+ Rack::Attack.blocklist("cdtb:block all PHP RQs") do |request|
39
+ request.path.end_with?("*.php")
40
+ end
41
+
42
+ if ENV["RACK_ATTACK_BLOCKED_IPS"].present?
43
+ blocked_ips_and_subnets= ENV["RACK_ATTACK_BLOCKED_IPS"].split(",")
44
+ Rack::Attack.blocklist("cdtb:block all unaccepted IPs") do |request|
45
+ ip= Cdtb::IpParser.extract_ip(request)
46
+ blocked_ips_and_subnets.any? { |ip_or_subnet| ip.start_with?(ip_or_subnet) }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Used internally by Rack::Request.trusted_proxy?(ip)
4
+ if ENV.key?("RACK_RQ_IP_FILTER_EXT") && ENV["RACK_RQ_IP_FILTER_EXT"].present?
5
+ ORIGINAL_REGEX= /\A127\.0\.0\.1\Z|\A(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|\A::1\Z|\Afd[0-9a-f]{2}:.+|\Alocalhost\Z|\Aunix\Z|\Aunix:/i
6
+ Rack::Request.ip_filter = lambda do |ip|
7
+ regex_str= ORIGINAL_REGEX.to_s
8
+ regex_str << ENV.fetch("RACK_RQ_IP_FILTER_EXT", nil)
9
+ /#{regex_str}/i.match?(ip)
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cdtb
4
+ # Parses IPs from Rack::Request objects, discarding the port.
5
+ module IpParser
6
+ def self.decorate_rack_request
7
+ Rack::Request.class_eval do
8
+ include Cdtb::IpParser
9
+
10
+ alias_method :original_ip_method, :ip
11
+
12
+ def ip
13
+ extract_ip(self)
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.extract_ip(request)
19
+ # Take the IP either from the remote addr or from the forwarded for header
20
+ # If Rack::Request is decorated use the original method.
21
+ ip= defined?(request.original_ip_method) ? request.original_ip_method : request.ip
22
+ Rails.logger.info { ">>>>>>>>>>>>>>>>>>>> Request IP: #{ip}" }
23
+ Rails.logger.info { ">>>>>>>>>>>>>>>>>>>> X-Forwarded-For: #{request.get_header("HTTP_X_FORWARDED_FOR")}" }
24
+
25
+ num_colons= ip.scan(":").length
26
+ if [1, 6].include?(num_colons)
27
+ # is an IP (v4 or v6) with port
28
+ ip.rpartition(":").first
29
+ else
30
+ # standard inet4 or inet6 IP without port
31
+ ip
32
+ end
33
+ end
34
+
35
+ def extract_ip(request)
36
+ ::Cdtb::IpParser.extract_ip(request)
37
+ end
38
+ end
39
+ end
@@ -7,8 +7,8 @@ module Decidim
7
7
  #
8
8
  # rubocop:disable Metrics/ClassLength
9
9
  class Remover < ::Decidim::Cdtb::Task
10
- def initialize(organization, csv_path, reporter_user_email)
11
- @organization= organization
10
+ def initialize(organization_id, csv_path, reporter_user_email)
11
+ @organization= Decidim::Organization.find_by(id: organization_id)
12
12
  @csv_path = csv_path
13
13
  @reporter_user_email = reporter_user_email
14
14
  progress_bar = { title: "Decidim::User" }
@@ -25,9 +25,7 @@ module Decidim
25
25
  def do_execution(context)
26
26
  progress_bar = context[:progress_bar]
27
27
 
28
- reporter_user = @organization.users.find_by(email: @reporter_user_email,
29
- organization: user.organization)
30
-
28
+ reporter_user = Decidim::User.find_by(email: @reporter_user_email, organization: @organization)
31
29
  emails_on_moderations = @organization.users.where(email_on_moderations: true).pluck(:email)
32
30
 
33
31
  disable_email_moderations(emails_on_moderations)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Cdtb
5
- VERSION = "0.5.4"
5
+ VERSION = "0.5.6"
6
6
  DECIDIM_MIN_VERSION = ">= 0.28.0"
7
7
  end
8
8
  end
@@ -6,7 +6,7 @@ require "decidim/cdtb/tasks"
6
6
  namespace :cdtb do
7
7
  namespace :participatory_spaces do
8
8
  desc <<~EODESC
9
- Add content blocks to a participatory processes
9
+ Add content blocks to participatory processes
10
10
  EODESC
11
11
  task :add_content_blocks, [:content_block_names] => :environment do |_task, args|
12
12
  unless Decidim.version >= "0.28"
data/lib/tasks/users.rake CHANGED
@@ -15,8 +15,8 @@ namespace :cdtb do
15
15
  desc <<~EODESC
16
16
  Remove Decidim::User's by IDs in a CSV.
17
17
  EODESC
18
- task :remove, %i[csv_path reporter_user_email] => [:environment] do |_taks, args|
19
- service = Decidim::Cdtb::Users::Remover.new(args.csv_path, args.reporter_user_email)
18
+ task :remove, %i[organization_id csv_path reporter_user_email] => [:environment] do |_taks, args|
19
+ service = Decidim::Cdtb::Users::Remover.new(args.organization_id, args.csv_path, args.reporter_user_email)
20
20
  service.execute!
21
21
  end
22
22
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-cdtb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Valls
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-07-21 00:00:00.000000000 Z
11
+ date: 2026-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim
@@ -86,8 +86,10 @@ files:
86
86
  - Rakefile
87
87
  - app/jobs/application_job.rb
88
88
  - app/jobs/cdtb/fix_nickname_job.rb
89
- - config/initializers/rack_attack.rb
89
+ - config/initializers/cdtb_rack_attack.rb
90
+ - config/initializers/ip_filtering.rb
90
91
  - decidim-cdtb.gemspec
92
+ - lib/cdtb/ip_parser.rb
91
93
  - lib/decidim/cdtb.rb
92
94
  - lib/decidim/cdtb/engine.rb
93
95
  - lib/decidim/cdtb/fixes/nickname_fixer.rb
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- unless ENV["CDTB_RACK_ATTACK_DISABLED"].to_i.positive? || %w[development test].include?(Rails.env)
4
- require "rack/attack"
5
-
6
- def extract_ip(request)
7
- x_forwarded_for= request.get_header("HTTP_X_FORWARDED_FOR")
8
- Rails.logger.info { ">>>>>>>>>>>>>>>>>>>> X-Forwarded-For: #{x_forwarded_for}" }
9
- if x_forwarded_for.present?
10
- x_forwarded_for.split(":").first
11
-
12
- else
13
- request.ip
14
- end
15
- end
16
-
17
- limit= ENV.fetch("RACK_ATTACK_THROTTLE_LIMIT", 30)
18
- period= ENV.fetch("RACK_ATTACK_THROTTLE_PERIOD", 60)
19
- Rails.logger.info("Configuring Rack::Attack.throttle with limit: #{limit}, period: #{period}")
20
- Rack::Attack.throttle("cdtb: requests by ip", limit: limit.to_i, period: period.to_i) do |request|
21
- # ignore requests to assets
22
- next if request.path.start_with?("/rails/active_storage")
23
-
24
- extract_ip(request)
25
- end
26
-
27
- limit= ENV.fetch("RACK_ATTACK_THROTTLE_RANGE_LIMIT", 30)
28
- period= ENV.fetch("RACK_ATTACK_THROTTLE_RANGE_PERIOD", 60)
29
- Rails.logger.info("Configuring Rack::Attack.throttle with limits for IP Ranges: #{limit}, period: #{period}")
30
- Rack::Attack.throttle("cdtb: requests by ip range", limit: limit.to_i, period: period.to_i) do |request|
31
- # ignore requests to assets
32
- next if request.path.start_with?("/rails/active_storage")
33
-
34
- ip= extract_ip(request)
35
- # rubocop: disable Lint/UselessAssignment
36
- range_32bit= ip.split(".")[0, 2]
37
- # rubocop: enable Lint/UselessAssignment
38
- end
39
-
40
- Rack::Attack.blocklist("cdtb: block all /.well-known/traffic-advice") do |request|
41
- request.path.start_with?("/.well-known/traffic-advice")
42
- end
43
-
44
- if ENV["RACK_ATTACK_BLOCKED_IPS"].present?
45
- blocked_ips_and_subnets= ENV["RACK_ATTACK_BLOCKED_IPS"].split(",")
46
- Rack::Attack.blocklist("cdtb:block all unaccepted IPs") do |request|
47
- ip= extract_ip(request)
48
- blocked_ips_and_subnets.any? { |ip_or_subnet| ip.start_with?(ip_or_subnet) }
49
- end
50
- end
51
- end