decidim-cdtb 0.1.7 → 0.1.9

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: 7ea237b7898bc194b0f63514d1f699d5cd1cf649ac7dd7433de19d9319541474
4
- data.tar.gz: be9a6f3251d35022b933524b3227edac2186a1c338a4025f6d73eb5495633e61
3
+ metadata.gz: 75ef34f5e24554377da1d31d2d17912828f34931343aeea22a03a79baeeeee27
4
+ data.tar.gz: 843c0aba1905b12edaeccbeffc6d6d5361c0eae9bc460882686edc0bde34a70f
5
5
  SHA512:
6
- metadata.gz: 3999c77a44817f3c0b3bc6b97663a47f3dade93f896958cdce06298bd9695d734cdd82859315607ecc3fcd990efd6e567e2e63d6e0141f5c3d256bc44d6b91ef
7
- data.tar.gz: 513123ffe284a654f47666d8a0e355b29cb3dd011a30bab73cdef0348776f45cd44dab8c8c9f23f5e962fb5f00a5dc9acb9d68a70ced7b39335cfc225ce56839
6
+ metadata.gz: 8f3b10d8e6c9bd8abdbb576b1f2faf0fe29cd4e49c511d0fb2a99d21044b38ce7d31bd21d4bc7d880d6e6f88cf7fa72b3938913b0b31706680a81075513a26a6
7
+ data.tar.gz: b591f9d9902bee32151d4f54e7675666d7870bea37fdab308708c7a8d7c1d175666e44aafa0cbcd871c47845cf2eec147650fe13a5b0836499f2f6af630088d4
data/.rubocop.yml CHANGED
@@ -32,7 +32,7 @@ Style/StringLiteralsInInterpolation:
32
32
  EnforcedStyle: double_quotes
33
33
 
34
34
  Layout/LineLength:
35
- Max: 120
35
+ Max: 140
36
36
 
37
37
  Layout/SpaceAroundOperators:
38
38
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.9] - 2024-05-08 (Dona'm gelat o l'hem liat)
4
+
5
+ - Include a versatile rack attack anti bots and crawlers.
6
+ - Add rake task to analyse logs for abusing IPs.
7
+
8
+ ## [0.1.8] - 2024-04-24 (Sapastre i bonastre)
9
+
10
+ - Fix spam users detector with deleted_at param and hide comments in remover users.
11
+
3
12
  ## [0.1.7] - 2024-04-22 (Emocions de colors)
4
13
 
5
14
  - Fix remove users task and add the reporter user mailer to arguments
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- decidim-cdtb (0.1.7)
4
+ decidim-cdtb (0.1.9)
5
5
  decidim (>= 0.26.2)
6
6
  rails (>= 6)
7
7
  ruby-progressbar
@@ -775,4 +775,4 @@ DEPENDENCIES
775
775
  sqlite3
776
776
 
777
777
  BUNDLED WITH
778
- 2.4.22
778
+ 2.3.6
data/README.md CHANGED
@@ -65,17 +65,35 @@ To migrate from S3 to local storage, the identified steps will be:
65
65
  `bin/rake cache:clear`
66
66
  5. Restart the Rails server
67
67
 
68
- ### Detect spam
68
+ ### Spam & bots
69
69
 
70
- To detect spam in Decidim.
70
+ Spam and bots are daily menaces in the current Internet. Decidim is not an exception, and is affected by both security concerns and performance.
71
+
72
+ #### Bad bots and crawlers
73
+
74
+ Decidim is already bundled with Rack::Attack but it lacks some features like IP banning or throttling by forwarded IP (useful when Decidim is behind a proxy). CDTB by default enables Rack::Attack with these features.
75
+
76
+ Four ENV variables exist to configure its behaviour:
77
+
78
+ - CDTB_RACK_ATTACK_DISABLED: Set to 1 to disable CDTB's Rack:Attack.
79
+ - RACK_ATTACK_THROTTLE_LIMIT: The max. allowed number of requests during the period. Defaults to 30.
80
+ - RACK_ATTACK_THROTTLE_PERIOD: The period in seconds. Defaults to 60.
81
+ - RACK_ATTACK_BLOCKED_IPS: A comma separated list of blocked IPs or subnets (in the form 1.2.3.0/32).
82
+
83
+
84
+ Available rake tasks to help analize crawlers:
85
+
86
+ - `bin/rake cdtb:logs:num_rq_per_ip` Counts the number of requests for each IP in the logs. Accepts a logfile param, it must be in log/.
71
87
 
72
88
  #### Detect spam users
89
+
73
90
  Detects users susceptible of being spammers. It can run on all organizations or be scoped to a single organization by passing the organization ID as the rake task parameter.
74
91
 
75
92
  This rake task export a .csv with a list of all the searched users. A column indicates if each user is suspicious of being a spammer or not.
76
93
  The columns in the CSV are: "ID, "Is suspicious?", "Name", "Email", "Nickname", "Personal URL", "About"
77
94
 
78
95
  Examples:
96
+
79
97
  `bin/rake cdtb:spam:users[org_id]` --> find users in organization with an id.
80
98
  `bin/rake cdtb:spam:users` --> find all users in all organizations.
81
99
 
@@ -0,0 +1,28 @@
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
+ limit= ENV["RACK_ATTACK_THROTTLE_LIMIT"] || 30
7
+ period= ENV["RACK_ATTACK_THROTTLE_PERIOD"] || 60
8
+ Rails.logger.info("Configuring Rack::Attack.throttle with limit: #{limit}, period: #{period}")
9
+ Rack::Attack.throttle("requests by (forwarded) ip", limit: limit.to_i, period: period.to_i) do |request|
10
+ # ignore requests to assets
11
+ next if request.path.start_with?("/rails/active_storage")
12
+
13
+ x_forwarded_for= request.get_header("HTTP_X_FORWARDED_FOR")
14
+ Rails.logger.info { ">>>>>>>>>>>>>>>>>>>> X-Forwarded-For: #{x_forwarded_for}" }
15
+ if x_forwarded_for.present?
16
+ ip= x_forwarded_for.split(":").first
17
+ ip
18
+ else
19
+ request.ip
20
+ end
21
+ end
22
+
23
+ if ENV["RACK_ATTACK_BLOCKED_IPS"].present?
24
+ ENV["RACK_ATTACK_BLOCKED_IPS"].split(",").each do |ip_or_subnet|
25
+ Rack::Attack.blocklist_ip(ip_or_subnet)
26
+ end
27
+ end
28
+ end
@@ -21,10 +21,12 @@ module Decidim
21
21
  end
22
22
 
23
23
  def prepare_execution(_ctx)
24
+ base_query = Decidim::User.where(deleted_at: nil)
25
+
24
26
  @users = if @organization.present?
25
- Decidim::User.where(organization: @organization)
27
+ base_query.where(organization: @organization)
26
28
  else
27
- Decidim::User.all
29
+ base_query
28
30
  end
29
31
 
30
32
  @num_users = @users.count
@@ -5,6 +5,7 @@ module Decidim
5
5
  module Users
6
6
  # Remove Decidim::User's
7
7
  #
8
+ # rubocop:disable Metrics/ClassLength
8
9
  class Remover < ::Decidim::Cdtb::Task
9
10
  def initialize(csv_path, reporter_user_email)
10
11
  @csv_path = csv_path
@@ -44,6 +45,7 @@ module Decidim
44
45
  def manage_comments(comments, user, reporter_user)
45
46
  comments.find_each do |comment|
46
47
  report_comment(comment, user, reporter_user)
48
+ hide_comment(comment, user, reporter_user) unless comment.hidden?
47
49
  end
48
50
  end
49
51
 
@@ -111,6 +113,18 @@ module Decidim
111
113
  end
112
114
  end
113
115
 
116
+ def hide_comment(comment, user, reporter_user)
117
+ Admin::HideResource.call(comment, reporter_user) do
118
+ on(:ok) do
119
+ puts "OK: Comment #{comment.id} of User #{user.id} hided"
120
+ end
121
+
122
+ on(:invalid) do
123
+ puts "ERROR: Comment #{comment.id} of User #{user.id} not hided"
124
+ end
125
+ end
126
+ end
127
+
114
128
  def context_for_report(user, comment, reporter_user)
115
129
  {
116
130
  current_organization: user.organization,
@@ -120,6 +134,7 @@ module Decidim
120
134
  }
121
135
  end
122
136
  end
137
+ # rubocop:enable Metrics/ClassLength
123
138
  end
124
139
  end
125
140
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Cdtb
5
- VERSION = "0.1.7"
5
+ VERSION = "0.1.9"
6
6
  DECIDIM_MIN_VERSION = ">= 0.26.2"
7
7
  end
8
8
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/cdtb/tasks"
4
+
5
+ namespace :cdtb do
6
+ namespace :verifications do
7
+ desc <<~EODESC
8
+ Lists the verifications handlers in the current Decidim application.
9
+ EODESC
10
+ task handlers: :environment do |_task, _args|
11
+ puts "Verification Handlers in this Decidim application:"
12
+ Decidim.authorization_handlers.each do |manifest|
13
+ attrs= if manifest.form.present?
14
+ manifest.form.constantize.attribute_set.to_a.map(&:name).excluding(:id, :user, :handler_name).join(", ")
15
+ else
16
+ "No form."
17
+ end
18
+ puts "- #{manifest.name}: (#{attrs})"
19
+ end
20
+ end
21
+
22
+ desc <<~EODESC
23
+ Returns the unique_id version of the given arguments for the given authorization handler.
24
+ Params:
25
+ - handler_name
26
+ - (optional) organization_id
27
+ - credential_1, credential_2, ...: in the form "id_document:00000000T", "birthdate:24/03/1977".
28
+ For example:
29
+ `bin/rake cdtb:verifications:to_unique_id[file_authorization_handler,id_document:00000000T,birthdate:01/01/2000]
30
+ `
31
+ EODESC
32
+ task :to_unique_id, [:handler_name] => :environment do |_task, args|
33
+ puts "Resolving #{args.handler_name} form class"
34
+ handler= find_handler_by_name(args.handler_name)
35
+ puts "Found handler with form class: #{handler.class}"
36
+
37
+ fill_handler_args(handler, args)
38
+
39
+ puts "unique_id: #{handler.unique_id}"
40
+ end
41
+
42
+ def find_handler_by_name(handler_name)
43
+ handler_class= Decidim::Verifications.find_workflow_manifest(handler_name).form
44
+ handler_class.constantize.new
45
+ end
46
+
47
+ def fill_handler_args(handler, args)
48
+ arguments= args.to_a[1..]
49
+ current_organization= if !arguments.first.include?(":")
50
+ Decidim::Organization.find(arguments.first)
51
+ else
52
+ Decidim::Organization.first
53
+ end
54
+ handler.with_context(current_organization: current_organization)
55
+
56
+ credentials= arguments.map { |arg| arg.split(":") }
57
+ puts "Setting credentials: #{credentials}"
58
+ credentials.each do |attr, val|
59
+ handler.send("#{attr}=".to_sym, val)
60
+ end
61
+ end
62
+
63
+ desc <<~EODESC
64
+ Checks the given credentials against the specified verification handler. Params [handler_name,credential1,credential2,...]"
65
+ EODESC
66
+ task :census_check, [:handler_name] => :environment do |_task, args|
67
+ handler= find_handler_by_name(args.handler_name)
68
+ fill_handler_args(handler, args)
69
+ raise "This handler does not support Cdtb's verification_service" unless handler.respond_to?(:verification_service)
70
+
71
+ service= handler.verification_service
72
+ puts "Invoking #{service.class.name}..."
73
+ rs= service.send_request
74
+ puts "Response Ok?: #{service.rs_ok?}"
75
+ puts "RS: #{rs.body}"
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :cdtb do
4
+ namespace :logs do
5
+ desc "Analize logs in Rails format. Counts the number of requests for each IP in the logs. Accepts a logfile param, it must be in log/."
6
+ task :num_rq_per_ip, [:logfile] do |_task, args|
7
+ logfile= args.logfile || "development.log"
8
+
9
+ file_path= "log/#{logfile}"
10
+ first_cmd= "grep Started"
11
+ piped_cmds= [%(grep " for "), "cut -d ' ' -f13", "sort", "uniq -c", "sort"].join(" | ")
12
+ puts "Running: `#{first_cmd} #{file_path} | #{piped_cmds}`"
13
+ puts `#{first_cmd} #{file_path} | #{piped_cmds}`
14
+ end
15
+ end
16
+ end
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.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Valls
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-22 00:00:00.000000000 Z
11
+ date: 2024-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim
@@ -100,6 +100,7 @@ files:
100
100
  - Rakefile
101
101
  - app/jobs/application_job.rb
102
102
  - app/jobs/cdtb/fix_nickname_job.rb
103
+ - config/initializers/rack_attack.rb
103
104
  - decidim-cdtb.gemspec
104
105
  - lib/decidim/cdtb.rb
105
106
  - lib/decidim/cdtb/engine.rb
@@ -120,6 +121,8 @@ files:
120
121
  - lib/generators/cdtb/templates/validate_migrations.yml
121
122
  - lib/generators/cdtb/validate_migrations_ci_generator.rb
122
123
  - lib/tasks/anonymize.rake
124
+ - lib/tasks/census.rake
125
+ - lib/tasks/logs.rake
123
126
  - lib/tasks/multitenants.rake
124
127
  - lib/tasks/spam.rake
125
128
  - lib/tasks/storage.rake