decidim-spam_signal 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +661 -0
  3. data/README.md +277 -0
  4. data/Rakefile +93 -0
  5. data/app/commands/decidim/comments/create_comment.rb +75 -0
  6. data/app/commands/decidim/spam_signal/admin/add_rule_command.rb +48 -0
  7. data/app/commands/decidim/spam_signal/admin/add_scanner_command.rb +46 -0
  8. data/app/commands/decidim/spam_signal/admin/remove_cop_command.rb +31 -0
  9. data/app/commands/decidim/spam_signal/admin/remove_rule_command.rb +31 -0
  10. data/app/commands/decidim/spam_signal/admin/remove_scanner_command.rb +31 -0
  11. data/app/commands/decidim/spam_signal/admin/update_cop_command.rb +41 -0
  12. data/app/commands/decidim/spam_signal/admin/update_rule_command.rb +47 -0
  13. data/app/commands/decidim/spam_signal/admin/update_scanner_command.rb +47 -0
  14. data/app/commands/decidim/spam_signal/application_handler.rb +27 -0
  15. data/app/commands/decidim/spam_signal/command.rb +14 -0
  16. data/app/commands/decidim/spam_signal/cops/cop_handler.rb +72 -0
  17. data/app/commands/decidim/spam_signal/cops/lock_cop_command.rb +58 -0
  18. data/app/commands/decidim/spam_signal/cops/sinalize_cop_command.rb +25 -0
  19. data/app/commands/decidim/spam_signal/scans/allowed_tlds_scan_command.rb +50 -0
  20. data/app/commands/decidim/spam_signal/scans/forbidden_tlds_scan_command.rb +49 -0
  21. data/app/commands/decidim/spam_signal/scans/scan_handler.rb +24 -0
  22. data/app/commands/decidim/spam_signal/scans/word_scan_command.rb +40 -0
  23. data/app/controllers/concerns/decidim/user_blocked_checker.rb +48 -0
  24. data/app/controllers/decidim/spam_signal/admin/application_controller.rb +18 -0
  25. data/app/controllers/decidim/spam_signal/admin/application_cops_controller.rb +122 -0
  26. data/app/controllers/decidim/spam_signal/admin/application_rules_controller.rb +136 -0
  27. data/app/controllers/decidim/spam_signal/admin/application_scans_controller.rb +110 -0
  28. data/app/controllers/decidim/spam_signal/admin/comment_cops_controller.rb +13 -0
  29. data/app/controllers/decidim/spam_signal/admin/comment_rules_controller.rb +13 -0
  30. data/app/controllers/decidim/spam_signal/admin/comment_scans_controller.rb +13 -0
  31. data/app/controllers/decidim/spam_signal/admin/profile_cops_controller.rb +13 -0
  32. data/app/controllers/decidim/spam_signal/admin/profile_rules_controller.rb +13 -0
  33. data/app/controllers/decidim/spam_signal/admin/profile_scans_controller.rb +13 -0
  34. data/app/controllers/decidim/spam_signal/admin/spam_filter_reports_controller.rb +41 -0
  35. data/app/forms/decidim/spam_signal/cops/lock_settings_form.rb +14 -0
  36. data/app/forms/decidim/spam_signal/cops/no_settings_form.rb +11 -0
  37. data/app/forms/decidim/spam_signal/cops/sinalize_settings_form.rb +13 -0
  38. data/app/forms/decidim/spam_signal/no_settings_form.rb +9 -0
  39. data/app/forms/decidim/spam_signal/rule_form.rb +10 -0
  40. data/app/forms/decidim/spam_signal/scans/allowed_tlds_form.rb +13 -0
  41. data/app/forms/decidim/spam_signal/scans/forbidden_tlds_form.rb +13 -0
  42. data/app/forms/decidim/spam_signal/scans/word_settings_form.rb +13 -0
  43. data/app/forms/decidim/spam_signal/settings_form.rb +27 -0
  44. data/app/helpers/decidim/spam_signal/admin/spam_signal_helper.rb +22 -0
  45. data/app/helpers/decidim/spam_signal/application_helper.rb +10 -0
  46. data/app/models/decidim/spam_signal/config.rb +48 -0
  47. data/app/overrides/profiles_noindex.rb +17 -0
  48. data/app/packs/images/decidim/spam_signal/entrypoints/spam_signal.js +1 -0
  49. data/app/packs/images/decidim/spam_signal/icon.svg +1 -0
  50. data/app/repositories/decidim/spam_signal/spam_config_repo.rb +160 -0
  51. data/app/views/decidim/admin/moderated_users/_report.html.erb +15 -0
  52. data/app/views/decidim/admin/moderated_users/index.html.erb +82 -0
  53. data/app/views/decidim/comments/comments/error.js.erb +4 -0
  54. data/app/views/decidim/spam_signal/admin/comment_cops/edit.html.erb +9 -0
  55. data/app/views/decidim/spam_signal/admin/comment_rules/edit.html.erb +8 -0
  56. data/app/views/decidim/spam_signal/admin/comment_rules/new.html.erb +9 -0
  57. data/app/views/decidim/spam_signal/admin/comment_scans/edit.html.erb +8 -0
  58. data/app/views/decidim/spam_signal/admin/comment_scans/new.html.erb +8 -0
  59. data/app/views/decidim/spam_signal/admin/profile_cops/edit.html.erb +9 -0
  60. data/app/views/decidim/spam_signal/admin/profile_rules/edit.html.erb +8 -0
  61. data/app/views/decidim/spam_signal/admin/profile_rules/new.html.erb +9 -0
  62. data/app/views/decidim/spam_signal/admin/profile_scans/edit.html.erb +7 -0
  63. data/app/views/decidim/spam_signal/admin/profile_scans/new.html.erb +8 -0
  64. data/app/views/decidim/spam_signal/admin/shared/cops/_edit.html.erb +48 -0
  65. data/app/views/decidim/spam_signal/admin/shared/rules/_edit.html.erb +27 -0
  66. data/app/views/decidim/spam_signal/admin/shared/rules/_new.html.erb +28 -0
  67. data/app/views/decidim/spam_signal/admin/shared/scans/_edit.html.erb +25 -0
  68. data/app/views/decidim/spam_signal/admin/shared/scans/_new.html.erb +39 -0
  69. data/app/views/decidim/spam_signal/admin/spam_filter_reports/index.html.erb +282 -0
  70. data/config/assets.rb +8 -0
  71. data/config/i18n-tasks.yml +9 -0
  72. data/config/initializers/spam_signal.rb +7 -0
  73. data/config/locales/en.yml +114 -0
  74. data/config/locales/fr.yml +115 -0
  75. data/config/routes.rb +3 -0
  76. data/lib/decidim/spam_signal/admin.rb +10 -0
  77. data/lib/decidim/spam_signal/admin_engine.rb +42 -0
  78. data/lib/decidim/spam_signal/cop_bot.rb +41 -0
  79. data/lib/decidim/spam_signal/cops/cops_repository.rb +37 -0
  80. data/lib/decidim/spam_signal/engine.rb +23 -0
  81. data/lib/decidim/spam_signal/extractors/comment_extractor.rb +15 -0
  82. data/lib/decidim/spam_signal/extractors/extractor.rb +13 -0
  83. data/lib/decidim/spam_signal/extractors/profile_extractor.rb +15 -0
  84. data/lib/decidim/spam_signal/scans/scans_repository.rb +44 -0
  85. data/lib/decidim/spam_signal/spam_settings_form_builder.rb +22 -0
  86. data/lib/decidim/spam_signal/test/factories.rb +24 -0
  87. data/lib/decidim/spam_signal/test/scan_factories.rb +17 -0
  88. data/lib/decidim/spam_signal/validators/comment_spam_validator.rb +119 -0
  89. data/lib/decidim/spam_signal/validators/profile_spam_validator.rb +133 -0
  90. data/lib/decidim/spam_signal/version.rb +14 -0
  91. data/lib/decidim/spam_signal.rb +31 -0
  92. data/lib/tasks/antispam.rb +23 -0
  93. metadata +210 -0
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Admin
6
+ class UpdateRuleCommand < Decidim::SpamSignal::Command
7
+ attr_reader :form,
8
+ :current_config,
9
+ :settings_repo,
10
+ :id
11
+
12
+ def initialize(config, settings_repo, form, id)
13
+ @current_config = config
14
+ @settings_repo = settings_repo
15
+ @form = form
16
+ @id = id
17
+ raise ArgumentError, "missing current_config" unless current_config
18
+ raise ArgumentError, "missing settings_repo" unless settings_repo
19
+ end
20
+
21
+ def call
22
+ return broadcast(:invalid) if form.invalid?
23
+ begin
24
+ rule = {}
25
+ rule["#{id}"] = attributes
26
+ rule["#{id}"]["handler_name"] = form.handler_name
27
+ settings_repo.set_rule(rule)
28
+ current_config.save_settings
29
+ broadcast(:ok, settings_repo)
30
+ rescue StandardError => e
31
+ broadcast(:invalid, e.message)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def form_blank?(form)
38
+ return true if form.nil?
39
+ attributes.blank?
40
+ end
41
+ def attributes
42
+ form.attributes.stringify_keys!
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Admin
6
+ class UpdateScannerCommand < Decidim::SpamSignal::Command
7
+ attr_reader :form,
8
+ :current_config,
9
+ :settings_repo
10
+
11
+ def initialize(config, settings_repo, form)
12
+ @current_config = config
13
+ @settings_repo = settings_repo
14
+ @form = form
15
+ raise ArgumentError, "missing current_config" unless current_config
16
+ raise ArgumentError, "missing settings_repo" unless settings_repo
17
+ end
18
+
19
+ def call
20
+ return broadcast(:invalid) if form.invalid?
21
+ return broadcast(:invalid) if attributes.blank?
22
+
23
+ begin
24
+ settings_repo.set_scan(
25
+ form.handler_name,
26
+ attributes
27
+ )
28
+ current_config.save_settings
29
+ broadcast(:ok, settings_repo)
30
+ rescue StandardError => e
31
+ broadcast(:invalid, e.message)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def form_blank?(form)
38
+ return true if form.nil?
39
+ attributes.blank?
40
+ end
41
+ def attributes
42
+ form.attributes.stringify_keys!
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ class ApplicationHandler < Decidim::SpamSignal::Command
6
+ def self.form
7
+ raise Error, "Handler need to define a form or return null"
8
+ end
9
+
10
+ def self.handler_name
11
+ name.demodulize.underscore.sub(/(_cop|_scan)(_form|_command)/, "")
12
+ end
13
+
14
+ def handler_name
15
+ self.class.handler_name
16
+ end
17
+
18
+ def self.i18n_key
19
+ raise Error, "Not Implemented"
20
+ end
21
+
22
+ def config
23
+ raise Error, "Not Implemented"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ # maintains compatibility with v0.26 which uses Rectify
6
+ if defined? ::Decidim::Command
7
+ class Command < ::Decidim::Command
8
+ end
9
+ else
10
+ class Command < ::Rectify::Command
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Cops
6
+ class CopHandler < ApplicationHandler
7
+ attr_reader :errors, :error_key, :suspicious_user, :justification, :admin_reporter, :config, :reportable, :current_organization
8
+
9
+ def initialize(
10
+ errors:,
11
+ error_key: :base,
12
+ suspicious_user:,
13
+ config:,
14
+ reportable: nil,
15
+ justification: nil,
16
+ admin_reporter: nil
17
+ )
18
+ @errors = errors
19
+ @error_key = error_key
20
+ @reportable = reportable || suspicious_user
21
+ @suspicious_user = suspicious_user
22
+ @current_organization = suspicious_user.organization
23
+
24
+ @config = config
25
+ @justification = justification
26
+ @admin_reporter = admin_reporter || CopBot.get(suspicious_user.organization)
27
+ end
28
+
29
+ def self.i18n_key
30
+ "decidim.spam_signal.cops.#{handler_name}"
31
+ end
32
+ def now_tag
33
+ "\n[#{DateTime.now.strftime("%d/%m/%Y %H:%M")}]"
34
+ end
35
+ def sinalize!(send_emails=true)
36
+ is_user_reported = reportable == suspicious_user
37
+ if is_user_reported
38
+ moderation = Decidim::UserModeration.find_or_create_by!(user: suspicious_user) do |moderation|
39
+ moderation.report_count = 0
40
+ end
41
+ else
42
+ moderation = Decidim::Moderation.find_or_create_by!(reportable: reportable, participatory_space: reportable.participatory_space) do |moderation|
43
+ moderation.report_count = 0
44
+ end
45
+ end
46
+ is_new = moderation.report_count == 0
47
+ moderation.update(report_count: moderation.report_count + 1)
48
+ if is_user_reported
49
+ user_report = Decidim::UserReport.find_or_create_by!(moderation: moderation) do |report|
50
+ report.moderation = moderation
51
+ report.user = admin_reporter
52
+ report.reason = "spam"
53
+ report.details = "#{now_tag}#{justification}"
54
+ end
55
+ else
56
+ user_report = Decidim::Report.find_or_create_by!(moderation: moderation) do |report|
57
+ report.moderation = moderation
58
+ report.user = admin_reporter
59
+ report.reason = "spam"
60
+ report.details = "#{now_tag}#{justification}"
61
+ end
62
+ end
63
+ # append the new bad things (to have a log).
64
+ user_report.update(details: "#{user_report.details}#{now_tag} #{justification}") unless is_new
65
+ admin_accountable = Decidim::User.where(admin: true, email: ENV.fetch("ANTISPAM_ADMIN", "antispam@example.org")).first
66
+ Decidim::UserReportJob.perform_later(admin, admin_reporter, "spam", reportable)
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Cops
6
+ class LockCopCommand < CopHandler
7
+ def self.form
8
+ ::Decidim::SpamSignal::Cops::LockSettingsForm
9
+ end
10
+
11
+ def call
12
+ errors.add(
13
+ error_key,
14
+ I18n.t("errors.spam",
15
+ scope: "decidim.spam_signal",
16
+ default: "this looks like spam."
17
+ )
18
+ ) unless config['forbid_creation_enabled']
19
+ unless suspicious_user.access_locked?
20
+ hide_comment! if config["hide_comments_enabled"]
21
+ sinalize! if config["sinalize_user_enabled"]
22
+ lock!
23
+ end
24
+ broadcast(config['forbid_creation_enabled'] ? :restore_value : :save)
25
+ end
26
+
27
+ private
28
+ def hide_comment!
29
+ suspicious_comments = Decidim::Comments::Comment.where(author: suspicious_user)
30
+ suspicious_comments.each do |spam|
31
+ moderation = Decidim::Moderation.find_or_create_by!(
32
+ reportable: spam,
33
+ participatory_space: spam.participatory_space
34
+ )
35
+ is_new = moderation.report_count == 0
36
+ moderation.update(reported_content: spam.body[admin_reporter.locale]) if !moderation.reported_content && spam.body[admin_reporter.locale]
37
+ report = Decidim::Report.find_or_create_by!(
38
+ moderation: moderation.reload,
39
+ user: admin_reporter) do |report|
40
+ report.locale = admin_reporter.locale
41
+ report.reason = "spam"
42
+ report.details = "#{now_tag}cascade: #{spam}"
43
+ end
44
+ report.update(details: "#{report.details}#{now_tag}cascade: #{spam}")unless is_new
45
+ moderation.update!(report_count: moderation.report_count + 1, hidden_at: Time.current)
46
+ end
47
+ end
48
+
49
+ def lock!
50
+ suspicious_user.lock_access!(
51
+ send_instructions: true
52
+ )
53
+ suspicious_user.save!(validate: false)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Cops
6
+ class SinalizeCopCommand < CopHandler
7
+ def self.form
8
+ ::Decidim::SpamSignal::Cops::SinalizeSettingsForm
9
+ end
10
+
11
+ def call
12
+ errors.add(
13
+ error_key,
14
+ I18n.t("errors.spam",
15
+ scope: "decidim.spam_signal",
16
+ default: "this looks like spam."
17
+ )
18
+ ) if config['forbid_creation_enabled']
19
+ sinalize!(config['send_emails_enabled'])
20
+ broadcast(config['forbid_creation_enabled'] ? :restore_value : :save)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Scans
6
+ class AllowedTldsScanCommand < ScanHandler
7
+ def self.form
8
+ ::Decidim::SpamSignal::Scans::AllowedTldsForm
9
+ end
10
+
11
+ def call
12
+ return broadcast(:ok) if allowed_tlds_csv.empty?
13
+ return broadcast(:ok) if all_allowed?
14
+ broadcast(:not_allowed_tlds_found)
15
+ end
16
+
17
+ def self.output_symbols
18
+ [:not_allowed_tlds_found]
19
+ end
20
+
21
+ private
22
+
23
+ def allowed_tlds_csv
24
+ @allowed_tlds_csv ||= (
25
+ config["allowed_tlds_csv"] || ""
26
+ ).split(",").map(&:strip).filter { |tlds| !tlds.empty? }
27
+ end
28
+
29
+ def all_allowed?
30
+ hosts.filter { |url| !allowed_tlds_csv.any? { |tld| url.include? tld } }.empty?
31
+ end
32
+
33
+ def hosts
34
+ URI.extract(suspicious_content, ["http", "https", "", "mailto" ]).map do |uri|
35
+ begin
36
+ (scheme, subdomain, host) = URI.split(uri)
37
+ host || ""
38
+ rescue URI::InvalidURIError
39
+ ""
40
+ end
41
+ end
42
+ end
43
+
44
+ def regex(patterns)
45
+ Regexp.union(patterns).source
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Scans
6
+ class ForbiddenTldsScanCommand < ScanHandler
7
+ def self.form
8
+ ::Decidim::SpamSignal::Scans::ForbiddenTldsForm
9
+ end
10
+
11
+ def call
12
+ return broadcast(:forbidden_tlds_found) if any_forbidden_tlds?
13
+ broadcast(:ok)
14
+ end
15
+
16
+ def self.output_symbols
17
+ [:forbidden_tlds_found]
18
+ end
19
+
20
+ private
21
+
22
+ def forbidden_tlds_csv
23
+ @forbidden_tlds_csv ||= (
24
+ config["forbidden_tlds_csv"] || ""
25
+ ).split(",").map(&:strip)
26
+ end
27
+
28
+ def any_forbidden_tlds?
29
+ hosts.filter { |url| forbidden_tlds_csv.any? { |tld| url.include? tld } }.present?
30
+ end
31
+
32
+ def hosts
33
+ URI.extract(suspicious_content, ["http", "https", "", "mailto" ]).map do |uri|
34
+ begin
35
+ (scheme, subdomain, host) = URI.split(uri)
36
+ host
37
+ rescue URI::InvalidURIError
38
+ ""
39
+ end
40
+ end
41
+ end
42
+
43
+ def regex(patterns)
44
+ Regexp.union(patterns).source
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Scans
6
+ class ScanHandler < ApplicationHandler
7
+ attr_reader :suspicious_content, :config
8
+
9
+ def initialize(suspicious_content, config)
10
+ @suspicious_content = suspicious_content
11
+ @config = config
12
+ end
13
+
14
+ def self.i18n_key
15
+ "decidim.spam_signal.scans.#{handler_name}"
16
+ end
17
+
18
+ def self.output_symbols
19
+ []
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Scans
6
+ class WordScanCommand < ScanHandler
7
+ def self.form
8
+ ::Decidim::SpamSignal::Scans::WordSettingsForm
9
+ end
10
+
11
+ def call
12
+ return broadcast(:ok) if suspicious_content.empty?
13
+ return broadcast(:word_found) if contains_stop_words?
14
+ broadcast(:ok)
15
+ end
16
+
17
+ def self.output_symbols
18
+ [:word_found]
19
+ end
20
+
21
+ private
22
+ def contains_stop_words?
23
+ @contains_stop_words ||= suspicious_content.match(
24
+ /#{regex(stop_list_words)}/i
25
+ ).to_s.present?
26
+ end
27
+
28
+ def regex(patterns)
29
+ Regexp.union(patterns).source
30
+ end
31
+
32
+ def stop_list_words
33
+ @stop_list_words ||= (
34
+ config["stop_list_words_csv"] || ""
35
+ ).split("\n").map(&:strip)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module UserBlockedChecker
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ before_action :check_user_not_blocked
11
+ around_action :store_request_metadata
12
+ end
13
+
14
+ def store_request_metadata
15
+ Thread.current[:current_request] = ::ActiveSupport::HashWithIndifferentAccess.new(
16
+ real_ip: request.ip || request.headers['X-Real-IP'],
17
+ user_agent: request.headers['User-Agent'],
18
+ xhr: request.xhr?,
19
+ id: request.request_id,
20
+ remote_ip: request.remote_ip,
21
+ referrer: request.headers['Refer'],
22
+ country: request.headers['X-GEO-COUNTRY-CODE']
23
+ )
24
+ yield
25
+ ensure
26
+ Thread.current[:current_request] = nil
27
+ end
28
+
29
+ def check_user_not_blocked
30
+ check_user_block_status(current_user)
31
+ end
32
+
33
+ def check_user_block_status(user)
34
+ if user.present? && user.blocked?
35
+ sign_out user
36
+ flash.delete(:notice)
37
+ flash[:error] = t("decidim.account.blocked")
38
+ root_path
39
+ end
40
+ if user.present? && user.access_locked?
41
+ sign_out user
42
+ flash.delete(:notice)
43
+ flash[:error] = t("decidim.account.locked")
44
+ root_path
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Admin
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Admin::Components::BaseController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ class ApplicationController < Decidim::Admin::ApplicationController
12
+ before_action do
13
+ enforce_permission_to :update, :organization, organization: current_organization
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ module Admin
6
+ class ApplicationCopsController < ApplicationController
7
+ include FormFactory
8
+ before_action :config
9
+ helper Decidim::SpamSignal::Admin::SpamSignalHelper
10
+ helper_method :cop_type, :available_cops, :current_config, :current_cop
11
+ def index
12
+ output_symbols = scan_repository.strategies.map do |scan_name|
13
+ scanKlass = scan_repository.strategy(scan_name)
14
+ scanKlass.output_symbols
15
+ end.flatten
16
+ end
17
+
18
+ def destroy
19
+ raise "Missing id" unless cop_type
20
+ RemoveCopCommand.call(
21
+ current_config,
22
+ resource_config,
23
+ cop_type
24
+ ) do |on|
25
+ on(:invalid) { flash[:alert] = "Can not remove the agent" }
26
+ on(:ok) { flash[:notice] = "Remove has been removed" }
27
+ redirect_to spam_filter_reports_path
28
+ end
29
+ end
30
+
31
+ def update
32
+ raise "No agent found" unless current_cop
33
+ form = current_cop.form.from_params(params.require("#{cop_key}")).with_context(
34
+ handler_name: current_cop.handler_name,
35
+ type: cop_type
36
+ )
37
+ UpdateCopCommand.call(
38
+ current_config,
39
+ resource_config,
40
+ form
41
+ ) do |on|
42
+ on(:invalid) { flash[:alert] = "Can not update the agent" }
43
+ on(:ok) { flash[:notice] = "Agent has been updated" }
44
+ redirect_to spam_filter_reports_path
45
+ end
46
+ end
47
+
48
+ def edit
49
+ @form = nil
50
+ if current_cop && current_cop.form
51
+ @form = current_cop.form.new(
52
+ **(resource_config.cop_options(current_cop.handler_name, cop_type) || {})
53
+ ).with_context(
54
+ config: current_config,
55
+ handler_name: current_cop.handler_name
56
+ )
57
+ elsif current_cop
58
+ @form = Decidim::SpamSignal::NoSettingsForm.new.with_context(
59
+ config: current_config,
60
+ handler_name: current_cop.handler_name
61
+ )
62
+ end
63
+ end
64
+
65
+ def create
66
+ raise "No scanner found" unless current_cop
67
+ form = current_cop.form.from_params(
68
+ params.require("#{cop_type}".to_sym)
69
+ ).with_context(
70
+ handler_name: current_cop.handler_name,
71
+ type: cop_type
72
+ )
73
+ AddScannerCommand.call(
74
+ current_config,
75
+ resource_config,
76
+ form
77
+ ) do |on|
78
+ on(:invalid) { flash[:alert] = "Can not create the agent" }
79
+ on(:ok) { flash[:notice] = "Agent has been created" }
80
+ redirect_to spam_filter_reports_path
81
+ end
82
+ end
83
+
84
+ def resource_config
85
+ raise Error, "Not implemented"
86
+ end
87
+ private
88
+ def available_cops
89
+ cop_repository.strategies.map do |cop, copKlass|
90
+ cop_repository.strategy cop
91
+ end
92
+ end
93
+
94
+ def cop_repository
95
+ Decidim::SpamSignal::Cops::CopsRepository.instance
96
+ end
97
+
98
+ def current_settings
99
+ resource_config
100
+ end
101
+ def cop_type
102
+ params.permit(:id)["id"] || nil
103
+ end
104
+ def cop_key
105
+ params.permit(:cop)["cop"] || nil
106
+ end
107
+
108
+ def current_cop
109
+ return nil unless cop_type && cop_key
110
+ cop_repository.strategy(cop_key)
111
+ end
112
+
113
+ def current_config
114
+ @current_config ||= Decidim::SpamSignal::Config.where(
115
+ id: params.require(:config_id),
116
+ organization: current_organization
117
+ ).first!
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end