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,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module SpamSignal
5
+ class SpamConfigRepo
6
+ attr_reader :handler_name
7
+ attr_reader :config
8
+ attr_accessor :errors
9
+ def initialize(handler_name, attributes)
10
+ @config = with_defaults(
11
+ attributes
12
+ )
13
+ @handler_name = handler_name
14
+ @errors = []
15
+ end
16
+
17
+ def valid?
18
+ # loop over all the scans, initialize the proper forms and validates them.
19
+ scans.each do |scan|
20
+ formKlass = scan.form
21
+ form = formKlass.from_model(scan)
22
+ @errors << form.errors.full_messages unless form.valid?
23
+ end
24
+ end
25
+
26
+ def scans; @config["scans"]; end
27
+ def rules; @config["rules"]; end
28
+ def spam_cop; @config["spam_cop"]; end
29
+ def suspicious_cop; @config["suspicious_cop"]; end
30
+
31
+ def rule(key)
32
+ rules["#{key}"]
33
+ end
34
+
35
+ def add_rule(r)
36
+ set_rule(r)
37
+ end
38
+
39
+ def set_rule(r)
40
+ rules.merge!(r)
41
+ end
42
+
43
+ def rm_rule(key)
44
+ rules.select! { |k, v| k != key }
45
+ end
46
+
47
+ def set_cop(cop)
48
+ attributes = validate_cop!(cop["handler_name"], cop)
49
+ attributes["handler_name"] = cop["handler_name"]
50
+ type = cop["type"]
51
+ if type == "spam"
52
+ @config["spam_cop"] = attributes
53
+ else
54
+ @config["suspicious_cop"] = attributes
55
+ end
56
+ end
57
+
58
+ def rm_cop(cop_type)
59
+ if cop_type == "spam"
60
+ @config["spam_cop"] = {}
61
+ else
62
+ @config["suspicious_cop"] = {}
63
+ end
64
+ end
65
+
66
+ def add_scan(scan, options = {})
67
+ set_scan(scan, options)
68
+ end
69
+
70
+ def set_scan(scan, options = {})
71
+ ensure_scan_name! scan
72
+ attributes = validate_scan!(scan, options)
73
+ scans["#{scan}"] = options
74
+ scans
75
+ end
76
+
77
+ def scan_strategy(scan)
78
+ ensure_scan_name! scan
79
+ scan_repository.strategy(scan)
80
+ end
81
+
82
+ def scan_options(scan)
83
+ ensure_scan_name! scan
84
+ scans["#{scan}"]
85
+ end
86
+
87
+ def cop_options(cop, cop_type)
88
+ ensure_cop_name! cop
89
+ if cop_type == "spam"
90
+ spam_cop
91
+ else
92
+ suspicious_cop
93
+ end
94
+ end
95
+
96
+ def validate_scan!(scan, options)
97
+ formScanKlass = form_scan(scan)
98
+ return {} unless formScanKlass
99
+ validator = formScanKlass.new(options).with_context(handler_name: scan)
100
+ raise Error, validator.errors unless validator.valid?
101
+ validator.attributes
102
+ end
103
+
104
+ def validate_cop!(cop, options)
105
+ formCopKlass = form_cop(cop)
106
+ return {} unless formCopKlass
107
+ validator = formCopKlass.new(options).with_context(handler_name: cop)
108
+ raise Error, validator.errors unless validator.valid?
109
+ validator.attributes
110
+ end
111
+
112
+ def rm_scan(scan)
113
+ scans.select! { |k| k != "#{scan}" }
114
+ end
115
+
116
+ private
117
+ def form_scan(scan)
118
+ ensure_scan_name! scan
119
+ scanner = scan_repository.strategy(scan)
120
+ scanner.form
121
+ end
122
+ def form_cop(cop)
123
+ ensure_cop_name! cop
124
+ cop_strategy = cops_repository.strategy(cop)
125
+ cop_strategy.form
126
+ end
127
+ def ensure_scan_name!(scan)
128
+ scan_sym = "#{scan}".to_sym
129
+ raise Error, "#{scan} is not a valid strategy #{scanners.join(",")}" unless scanners.include? scan_sym
130
+ end
131
+ def ensure_cop_name!(cop)
132
+ cop_sym = "#{cop}".to_sym
133
+ raise Error, "#{cop} is not a valid strategy #{cops.join(",")}" unless cops.include? cop_sym
134
+ end
135
+ def with_defaults(conf)
136
+ conf["scans"] ||= {}
137
+ conf["rules"] ||= {}
138
+ conf["spam_cop"] ||= {}
139
+ conf["suspicious_cop"] ||= {}
140
+ conf
141
+ end
142
+
143
+ def scanners
144
+ scan_repository.strategies
145
+ end
146
+
147
+ def scan_repository
148
+ Scans::ScansRepository.instance
149
+ end
150
+
151
+ def cops
152
+ cops_repository.strategies
153
+ end
154
+
155
+ def cops_repository
156
+ Cops::CopsRepository.instance
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,15 @@
1
+ <% unless report.details.blank? %>
2
+ <div class="reveal" id="report-<%= report.id %>" data-reveal>
3
+ <h1><%= t(".reasons.#{report.reason}") %></h1>
4
+ <ol>
5
+ <% report.details.split("\n").each do |line| %>
6
+ <li><%= line %></li>
7
+ <% end %>
8
+ </ol>
9
+ <button class="close-button" data-close aria-label="Close modal" type="button">
10
+ <span aria-hidden="true">&times;</span>
11
+ </button>
12
+ </div>
13
+
14
+ <button class="button tiny" style="margin-bottom: 0;" data-open="report-<%= report.id %>"><%= t(".reasons.#{report.reason}") %></button>
15
+ <% end %>
@@ -0,0 +1,82 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="card with-overflow">
3
+ <div class="card-divider">
4
+ <h2 class="card-title">
5
+ <%= t(".title") %>
6
+ </h2>
7
+
8
+ <h2 class="card-title">
9
+ <div class="inline-block" style="float: right; text-align: right">
10
+ <table>
11
+ <tbody>
12
+ <tr>
13
+ <td>
14
+ <%= link_to moderated_users_path(blocked: false), class: "btn btn-small" do %>
15
+ <%= t("decidim.admin.moderated_users.tabs.unblocked") %>
16
+ <% end %>
17
+ </td>
18
+ <td>|</td>
19
+ <td>
20
+ <%= link_to moderated_users_path(blocked: true), class: "btn btn-small" do %>
21
+ <%= t("decidim.admin.moderated_users.tabs.blocked") %>
22
+ <% end %>
23
+ </td>
24
+ </tr>
25
+ </tbody>
26
+ </table>
27
+ </div>
28
+ </h2>
29
+ </div>
30
+
31
+ <%= admin_filter_selector(:moderated_users) %>
32
+
33
+ <div class="card-section">
34
+ <div class="table-scroll">
35
+ <table class="table-list">
36
+ <thead>
37
+ <tr>
38
+ <th><%= t(".name") %></th>
39
+ <th><%= t(".nickname") %></th>
40
+ <th><%= t(".reason") %></th>
41
+ <th><%= sort_link(query, :report_count, t(".reports"), default_order: :desc) %></th>
42
+ <th class="actions"><%= t(".actions.title") %></th>
43
+ </tr>
44
+ </thead>
45
+ <tbody>
46
+ <% @moderated_users.each do |moderation| %>
47
+ <tr data-id="<%= moderation.id %>">
48
+ <% if moderation.user.nickname.present? %>
49
+ <td><%= link_to moderation.user.name, decidim.profile_path(moderation.user.nickname) %></td>
50
+ <td><%= link_to moderation.user.nickname, decidim.profile_path(moderation.user.nickname) %></td>
51
+ <% else %>
52
+ <td><%= moderation.user.name %></td>
53
+ <td><%= moderation.user.nickname %></td>
54
+ <% end %>
55
+ <td>
56
+ <% reports = moderation.reports.map { |report| render "report", report: report } %>
57
+ <%= safe_join(reports, ",") %>
58
+ </td>
59
+ <td>
60
+ <%= moderation.report_count %>
61
+ </td>
62
+
63
+ <td class="actions">
64
+ <% if !moderation.user.blocked? && allowed_to?(:unreport, :moderate_users) %>
65
+ <%= icon_link_to "action-undo", ignore_moderated_user_path(id: moderation), t(".actions.unreport"), class: "action-icon--unreport", method: :put %>
66
+ <% end %>
67
+ <% if allowed_to?(:block, :moderate_users) %>
68
+ <% if moderation.user.blocked? %>
69
+ <%= icon_link_to "ban", user_block_path(user_id: moderation.user.id), t(".actions.unblock"), class: "action-icon action-icon--disabled", method: :delete %>
70
+ <% else %>
71
+ <%= icon_link_to "ban", new_user_block_path(user_id: moderation.user.id), t(".actions.block"), class: "action-icon action-icon" %>
72
+ <% end %>
73
+ <% end %>
74
+ </td>
75
+ </tr>
76
+ <% end %>
77
+ </tbody>
78
+ </table>
79
+ <%= paginate @moderated_users, theme: "decidim" %>
80
+ </div>
81
+ </div>
82
+ </div>
@@ -0,0 +1,4 @@
1
+ if(window && window.location && window.location.reload)
2
+ window.location.reload();
3
+ else
4
+ alert("Comment creation error");
@@ -0,0 +1,9 @@
1
+ <%= render "decidim/spam_signal/admin/shared/cops/edit",
2
+ locals: {
3
+ update_path: "config_comment_cop_path",
4
+ edit_path: "edit_config_comment_cop_path",
5
+ destroy_path: "config_comment_cop_path",
6
+ i18n_scope: "decidim.spam_signal.admin.comment_cops.edit",
7
+ form: @form
8
+ }
9
+ %>
@@ -0,0 +1,8 @@
1
+ <%= render "decidim/spam_signal/admin/shared/rules/edit",
2
+ locals: {
3
+ update_path: "config_comment_rule_path",
4
+ destroy_path: "config_comment_rule_path",
5
+ i18n_scope: "decidim.spam_signal.admin.comment_rules.edit",
6
+ form: @form
7
+ }
8
+ %>
@@ -0,0 +1,9 @@
1
+ <%= render "decidim/spam_signal/admin/shared/rules/new",
2
+ locals: {
3
+ create_path: "config_comment_rules_path",
4
+ destroy_path: "config_comment_rule_path",
5
+ i18n_scope: "decidim.spam_signal.admin.comment_rules.new",
6
+ form: @form,
7
+ rule_type: rule_type
8
+ }
9
+ %>
@@ -0,0 +1,8 @@
1
+ <%= render "decidim/spam_signal/admin/shared/scans/edit",
2
+ locals: {
3
+ update_path: "config_comment_scan_path",
4
+ destroy_path: "config_comment_scan_path",
5
+ i18n_scope: "decidim.spam_signal.admin.comment_scans.edit",
6
+ current_scanner: current_scanner
7
+ }
8
+ %>
@@ -0,0 +1,8 @@
1
+ <%= render "decidim/spam_signal/admin/shared/scans/new",
2
+ locals: {
3
+ new_path: "new_config_comment_scan_path",
4
+ create_path: "config_comment_scans_path",
5
+ destroy_path: "config_comment_scan_path",
6
+ i18n_scope: "decidim.spam_signal.admin.comment_scans.new"
7
+ }
8
+ %>
@@ -0,0 +1,9 @@
1
+ <%= render "decidim/spam_signal/admin/shared/cops/edit",
2
+ locals: {
3
+ update_path: "config_profile_cop_path",
4
+ edit_path: "edit_config_profile_cop_path",
5
+ destroy_path: "config_profile_cop_path",
6
+ i18n_scope: "decidim.spam_signal.admin.profile_cops.edit",
7
+ form: @form
8
+ }
9
+ %>
@@ -0,0 +1,8 @@
1
+ <%= render "decidim/spam_signal/admin/shared/rules/edit",
2
+ locals: {
3
+ update_path: "config_profile_rule_path",
4
+ destroy_path: "config_profile_rule_path",
5
+ i18n_scope: "decidim.spam_signal.admin.profile_rules.edit",
6
+ form: @form
7
+ }
8
+ %>
@@ -0,0 +1,9 @@
1
+ <%= render "decidim/spam_signal/admin/shared/rules/new",
2
+ locals: {
3
+ create_path: "config_profile_rules_path",
4
+ destroy_path: "config_profile_rule_path",
5
+ i18n_scope: "decidim.spam_signal.admin.profile_rules.new",
6
+ form: @form,
7
+ rule_type: rule_type
8
+ }
9
+ %>
@@ -0,0 +1,7 @@
1
+ <%= render "decidim/spam_signal/admin/shared/scans/edit",
2
+ locals: {
3
+ update_path: "config_profile_scan_path",
4
+ destroy_path: "config_profile_scan_path",
5
+ i18n_scope: "decidim.spam_signal.admin.profile_scans.edit"
6
+ }
7
+ %>
@@ -0,0 +1,8 @@
1
+ <%= render "decidim/spam_signal/admin/shared/scans/new",
2
+ locals: {
3
+ new_path: "new_config_profile_scan_path",
4
+ create_path: "config_profile_scans_path",
5
+ destroy_path: "config_profile_scan_path",
6
+ i18n_scope: "decidim.spam_signal.admin.profile_scans.new"
7
+ }
8
+ %>
@@ -0,0 +1,48 @@
1
+ <% form = locals[:form] %>
2
+ <%= link_to("Go back", spam_filter_reports_path) %>
3
+ <% if form %>
4
+ <div class="content spam_signal__section">
5
+ <h1><%= t("headings.title", type: cop_type, scope: locals[:i18n_scope]) %> (2/2)</h1>
6
+ <div>
7
+ <div class="grid-x grid-margin-y callout">
8
+ <div class="cell small-10">
9
+ <strong><%= t("#{current_cop.i18n_key}.name").upcase %></strong><br />
10
+ <em><%= t("#{current_cop.i18n_key}.description", default: "") %></em>
11
+ </div>
12
+ <div class="cell small-2">
13
+ <%= button_to("Remove the agent", routes.send(locals[:destroy_path], config_id: current_config.id, id: cop_type), method: :delete, class: "button small alert") %>
14
+ </div>
15
+ </div>
16
+ <div class="form-fields callout">
17
+ <% unless form.attributes.empty? %>
18
+ <div class="form-fields">
19
+ <%= decidim_form_for(form, url: routes.send(locals[:update_path], current_config.id, cop_type), builder: Decidim::SpamSignal::SpamSettingsFormBuilder, method: :patch) do |f| %>
20
+ <h5><%= t("form", type: t("#{current_cop.i18n_key}.name"), scope: locals[:i18n_scope]) %></h5>
21
+
22
+ <%= f.all_fields %>
23
+ <input type="hidden" name="cop" value="<%= current_cop.handler_name %>" />
24
+ <div class="actions">
25
+ <%= f.submit t("decidim.spam_signal.admin.actions.save") %>
26
+ </div>
27
+ <% end %>
28
+ </div>
29
+ <% else %>
30
+ <h5><em>There are no option for this agent</em></h5>
31
+ <% end %>
32
+ </div>
33
+ <% else %>
34
+ <div class="content spam_signal__section">
35
+ <h1><%= t("headings.title", type: cop_type, scope: locals[:i18n_scope]) %> (2/2)</h1>
36
+ <div>
37
+ <div class="callout">
38
+ <h2><%= t("headings.choose_cop", type: cop_type, scope: locals[:i18n_scope]) %></h2>
39
+ <div class="stacked button-group">
40
+ <% available_cops.each do |cop| %>
41
+ <%= link_to(routes.send(locals[:edit_path], config_id: current_config.id, id: cop_type, cop: cop.handler_name), class: "button") do %>
42
+ <strong><%= t("#{cop.i18n_key}.name").upcase %></strong><br />
43
+ <em><%= t("#{cop.i18n_key}.description", default: "") %></em>
44
+ <% end %>
45
+ <% end %>
46
+ </div>
47
+ </div>
48
+ <% end %>
@@ -0,0 +1,27 @@
1
+ <%= link_to("Go back", spam_filter_reports_path) %>
2
+
3
+ <% form = locals[:form] %>
4
+ <div class="grid-x grid-margin-y callout">
5
+ <div class="cell small-10">
6
+ <strong><%= form.rules.keys.map(&:to_s).join(" AND ") %></strong><br />
7
+ <em><%= t("description", type: form.context.handler_name, scope: locals[:i18n_scope]) %></em>
8
+ </div>
9
+ <div class="cell small-2">
10
+ <%= button_to("🗑 Remove the rule", routes.send(locals[:destroy_path], config_id: current_config.id, id: form.context.id), method: :delete, class: "button small alert") %>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="callout">
15
+ <%= decidim_form_for(form, builder: Decidim::SpamSignal::SpamSettingsFormBuilder, url: routes.send(locals[:update_path], current_config.id, form.context.id), method: :patch, html: {id: "EditRule"}) do |f| %>
16
+ <h5><%= t("headings.caption", scope: locals[:i18n_scope]) %></h5>
17
+ <% available_symbols.map {|s| "#{s}" }.each do |symbol| %>
18
+ <label for="EditRule<%= symbol.upcase %>">
19
+ <input id="EditRule<%= symbol.upcase %>" type="checkbox" name="rules[<%=form.context.id%>][<%= symbol %>]" value="true" <%= 'checked="checked"' if form.rules["#{symbol}".to_sym]%> />
20
+ <%= symbol.titleize %>
21
+ </label>
22
+ <% end %>
23
+ <div class="actions">
24
+ <%= f.submit t("decidim.spam_signal.admin.actions.save") %>
25
+ </div>
26
+ <% end %>
27
+ </div>
@@ -0,0 +1,28 @@
1
+ <%= link_to("Go back", spam_filter_reports_path) %>
2
+
3
+ <% form = locals[:form] %>
4
+
5
+ <div class="grid-x grid-margin-y callout">
6
+ <div class="cell small-10">
7
+ <strong><%= t("headings.title", type: rule_type, scope: locals[:i18n_scope]).upcase %></strong><br />
8
+ <em><%= t("description", type: rule_type, scope: locals[:i18n_scope]) %></em>
9
+ </div>
10
+ </div>
11
+
12
+ <div class="callout">
13
+ <%= decidim_form_for(form, builder: Decidim::SpamSignal::SpamSettingsFormBuilder, url: routes.send(locals[:create_path], current_config.id), method: :post, html: {id: "NewRule"}) do |f| %>
14
+ <h5><%= t("headings.caption", scope: locals[:i18n_scope]) %></h5>
15
+ <% new_id = uuid %>
16
+ <% available_symbols.map {|s| "#{s}" }.each do |symbol| %>
17
+ <label for="NewRule<%= symbol.upcase %>">
18
+ <input id="NewRule<%= symbol.upcase %>" type="checkbox" name="rules[<%=new_id%>][<%= symbol %>]" value="true" />
19
+ <%= symbol.titleize %>
20
+ </label>
21
+ <% end %>
22
+ <input id="NewRuleType" type="hidden" name="rule" value="<%= rule_type %>" />
23
+
24
+ <div class="actions">
25
+ <%= f.submit "save" %>
26
+ </div>
27
+ <% end %>
28
+ </div>
@@ -0,0 +1,25 @@
1
+ <%= link_to("Go back", spam_filter_reports_path) %>
2
+ <h1><%= t("headings.title", scan: t("name", scope: current_scanner.i18n_key) ,scope: locals[:i18n_scope]) %></h1>
3
+
4
+ <div class="grid-x grid-margin-y callout">
5
+ <div class="cell small-10">
6
+ <strong><%= t("name", scope: current_scanner.i18n_key).upcase %></strong><br />
7
+ <em><%= t("description", scope: current_scanner.i18n_key) %></em>
8
+ </div>
9
+ <div class="cell small-2">
10
+ <%= button_to("🗑 Remove scan", routes.send(locals[:destroy_path], config_id: current_config.id, id: current_scanner.handler_name), method: :delete, class: "button small alert") %>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="form-fields">
15
+ <%= decidim_form_for(@form, url: routes.send(locals[:update_path], current_config.id, current_scanner.handler_name), builder: Decidim::SpamSignal::SpamSettingsFormBuilder, method: :patch, html: {class: "callout"}) do |f| %>
16
+ <h5><%= t("headings.caption", scan: t("name", scope: current_scanner.i18n_key) ,scope: locals[:i18n_scope]) %></h5>
17
+ <%= f.all_fields %>
18
+ <input type="hidden" name="id" value="<%= current_scanner.handler_name %>" />
19
+ <div class="actions">
20
+ <%= f.submit t("decidim.spam_signal.admin.actions.save") %>
21
+ </div>
22
+ <% end %>
23
+
24
+ </div>
25
+ </div>
@@ -0,0 +1,39 @@
1
+ <%= link_to("Go back", spam_filter_reports_path) %>
2
+
3
+ <div class="content spam_signal__section">
4
+ <h1 class="card-title">
5
+ <%= t("headings.title", scope: locals[:i18n_scope]).upcase %> (<% if @form %>2<% else %>1<% end %>/2)
6
+ </h1>
7
+ <div>
8
+
9
+ <% if @form %>
10
+ <div class="grid-x grid-margin-y callout">
11
+ <div class="cell small-10">
12
+ <strong><%= t("name", scope: current_scanner.i18n_key).upcase %></strong><br />
13
+ <em><%= t("description", scope: current_scanner.i18n_key) %></em>
14
+ </div>
15
+ </div>
16
+ <%= decidim_form_for(@form, url: routes.send(locals[:create_path], config_id: current_config.id), builder: Decidim::SpamSignal::SpamSettingsFormBuilder, method: :post, html: {class: "callout"}) do |f| %>
17
+ <div class="form-fields">
18
+ <em><%= t("#{current_scanner.i18n_key}.description", default: "") %></em>
19
+ <%= f.all_fields %>
20
+ <input type="hidden" name="id" value="<%= current_scanner.handler_name %>" />
21
+ <div class="actions">
22
+ <%= f.submit t("decidim.spam_signal.admin.actions.save") %>
23
+ </div>
24
+ </div>
25
+ <% end %>
26
+ <% else %>
27
+ <div class="callout">
28
+ <h2><%= t("headings.choose_scan", scope: locals[:i18n_scope]) %></h2>
29
+ <div class="stacked button-group">
30
+ <% available_scanners.each do |scan| %>
31
+ <%= link_to(routes.send(locals[:new_path], config_id: current_config.id, id: scan.handler_name), class: "button") do %>
32
+ <strong><%= t("#{scan.i18n_key}.name").upcase %></strong><br />
33
+ <em><%= t("#{scan.i18n_key}.description", default: "") %></em>
34
+ <% end %>
35
+ <% end %>
36
+ </div>
37
+ </div>
38
+ <% end %>
39
+ </div>