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 +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +2 -2
- data/README.md +20 -2
- data/config/initializers/rack_attack.rb +28 -0
- data/lib/decidim/cdtb/spam/user_spam_detector.rb +4 -2
- data/lib/decidim/cdtb/users/remover.rb +15 -0
- data/lib/decidim/cdtb/version.rb +1 -1
- data/lib/tasks/census.rake +78 -0
- data/lib/tasks/logs.rake +16 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75ef34f5e24554377da1d31d2d17912828f34931343aeea22a03a79baeeeee27
|
4
|
+
data.tar.gz: 843c0aba1905b12edaeccbeffc6d6d5361c0eae9bc460882686edc0bde34a70f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f3b10d8e6c9bd8abdbb576b1f2faf0fe29cd4e49c511d0fb2a99d21044b38ce7d31bd21d4bc7d880d6e6f88cf7fa72b3938913b0b31706680a81075513a26a6
|
7
|
+
data.tar.gz: b591f9d9902bee32151d4f54e7675666d7870bea37fdab308708c7a8d7c1d175666e44aafa0cbcd871c47845cf2eec147650fe13a5b0836499f2f6af630088d4
|
data/.rubocop.yml
CHANGED
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
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
|
-
###
|
68
|
+
### Spam & bots
|
69
69
|
|
70
|
-
|
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
|
-
|
27
|
+
base_query.where(organization: @organization)
|
26
28
|
else
|
27
|
-
|
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
|
data/lib/decidim/cdtb/version.rb
CHANGED
@@ -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
|
data/lib/tasks/logs.rake
ADDED
@@ -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.
|
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-
|
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
|