Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.1.0 #27

Merged
merged 2 commits into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ jobs:
- uses: nanasess/[email protected]
- name: Run precompile if needed
run: |
if [[ -d ./spec/system && -n "$(ls -A ./spec/system)" ]]; then
rails assets:precompile
if [[ -d "app/views" ]] || [[ -d "spec/mailers" ]] || [[ -d "spec/system" ]]; then
cd "spec/decidim_dummy_app"
bundle exec rails assets:precompile
else
echo "No need to precompile assets since system folder is empty"
fi
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
decidim-spam_detection (1.0.0)
decidim-spam_detection (1.1.0)
decidim-core (~> 0.25)

GEM
Expand Down
19 changes: 19 additions & 0 deletions app/jobs/decidim/spam_detection/notify_admins.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Decidim
module SpamDetection
class NotifyAdmins < ApplicationJob
queue_as :default

def perform(results_hash)
results_hash.each do |id, result|
next if result.keys == [:nothing]

Decidim::Organization.find(id).admins.each do |admin|
Decidim::SpamDetection::SpamDetectionMailer.notify_detection(admin, result).deliver_later
end
end
end
end
end
end
19 changes: 19 additions & 0 deletions app/mailers/decidim/spam_detection/spam_detection_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Decidim
module SpamDetection
class SpamDetectionMailer < Decidim::ApplicationMailer
def notify_detection(user, results)
with_user(user) do
@reported_count = results[:reported_user]
@blocked_count = results[:blocked_user]
@organization = user.organization
@user = user

subject = I18n.t("notify_detection.subject", scope: "decidim.spam_detection_mailer")
mail(to: @user.email, subject: subject)
end
end
end
end
end
26 changes: 23 additions & 3 deletions app/services/decidim/spam_detection/mark_users_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def initialize
.where(admin: false, blocked: false, deleted_at: nil)
.where("(extended_data #> '{spam_detection, unreported_at}') is null")
.where("(extended_data #> '{spam_detection, unblocked_at}') is null")
@results = []
@results = {}
end

def self.call
Expand All @@ -38,11 +38,15 @@ def ask_and_mark
spam_probability_array = Decidim::SpamDetection::ApiProxy.request(cleaned_users)

mark_spam_users(merge_response_with_users(spam_probability_array))
notify_admins!
end

def mark_spam_users(probability_array)
probability_array.each do |probability_hash|
@results << Decidim::SpamDetection::SpamUserCommandAdapter.call(probability_hash).result
result = Decidim::SpamDetection::SpamUserCommandAdapter.call(probability_hash).result
organization_id = probability_hash["decidim_organization_id"]

add_to_results(organization_id.to_s, result)
end
end

Expand All @@ -56,7 +60,23 @@ def merge_response_with_users(response)
end

def status
@results.tally
@results.each_with_object({}) do |result, hash|
hash[result[0]] = result[1].tally
end
end

def notify_admins!
Decidim::SpamDetection::NotifyAdmins.perform_later(status)
end

private

def add_to_results(organization_id, result)
if @results[organization_id]
@results[organization_id] << result
else
@results[organization_id] = [result]
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p class="email-greeting"><%= t(".hello", name: @user.name) %></p>
<p><%= t(".intro") %></p>

<% if @reported_count.present? %>
<p>
<%= t(".reported_count", count: @reported_count) %>
</p>
<% end %>

<% if @blocked_count.present? %>
<p>
<%= t(".blocked_count", count: @blocked_count) %>
</p>
<% end %>
9 changes: 0 additions & 9 deletions config/assets.rb

This file was deleted.

2 changes: 1 addition & 1 deletion config/i18n-tasks.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---

base_locale: en
locales: [en]
locales: [en, fr, es, ca]

ignore_unused:
- "decidim.components.spam_detection.name"
Expand Down
16 changes: 16 additions & 0 deletions config/locales/ca.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
ca:
decidim:
components:
spam_detection:
name: SpamDetection
spam_detection:
spam_detection_mailer:
notify_detection:
blocked_count: blocked_count %{count}
hello: Hello %{name}
intro: Aquí teniu l'informe de la tasca de detecció de correu brossa
reported_count: reported_count %{count}
spam_detection_mailer:
notify_detection:
subject: Resum de detecció de correu brossa
10 changes: 10 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ en:
components:
spam_detection:
name: SpamDetection
spam_detection:
spam_detection_mailer:
notify_detection:
blocked_count: 'Blocked users count: %{count}'
hello: Hello %{name}
intro: Here is the report of the spam detection task
reported_count: 'Reported users count: %{count}'
spam_detection_mailer:
notify_detection:
subject: Spam detection digest
16 changes: 16 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
es:
decidim:
components:
spam_detection:
name: SpamDetection
spam_detection:
spam_detection_mailer:
notify_detection:
blocked_count: blocked_count %{count}
hello: Hello %{name}
intro: Here is the report of the spam detection task
reported_count: reported_count %{count}
spam_detection_mailer:
notify_detection:
subject: Subject
16 changes: 16 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
fr:
decidim:
components:
spam_detection:
name: SpamDetection
spam_detection:
spam_detection_mailer:
notify_detection:
blocked_count: blocked_count %{count}
hello: Hello %{name}
intro: Here is the report of the spam detection task
reported_count: reported_count %{count}
spam_detection_mailer:
notify_detection:
subject: Subject
15 changes: 12 additions & 3 deletions lib/decidim/spam_detection/abstract_spam_user_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ def call
raise NotImplementedError
end

def reason
raise NotImplementedError
end

def details
raise NotImplementedError
end

def moderation_user
moderation_admin_params = {
name: SPAM_USER[:name],
Expand Down Expand Up @@ -56,9 +64,10 @@ def create_moderation_admin(params)
end

def add_spam_detection_metadata!(metadata)
@user.update!(extended_data: @user.extended_data
.dup
.deep_merge("spam_detection" => metadata))
@user.extended_data = @user.extended_data
.dup
.deep_merge("spam_detection" => metadata)
@user.save(validate: false)
end
end
end
Expand Down
64 changes: 48 additions & 16 deletions lib/decidim/spam_detection/block_spam_user_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,60 @@ class BlockSpamUserCommand < Decidim::SpamDetection::AbstractSpamUserCommand
prepend Decidim::SpamDetection::Command

def call
form = form(Decidim::Admin::BlockUserForm).from_params(
justification: "The user was blocked because of a high spam probability by Decidim spam detection bot"
)
ActiveRecord::Base.transaction do
create_user_moderation
block!
register_justification!
notify_user!
add_spam_detection_metadata!({ "blocked_at" => Time.current, "spam_probability" => @probability })
end

moderator = @moderator
user = @user
Rails.logger.info("User with id #{@user["id"]} was blocked for spam with a probability of #{@probability}%")

form.define_singleton_method(:user) { user }
form.define_singleton_method(:current_user) { moderator }
form.define_singleton_method(:blocking_user) { moderator }

Decidim::Admin::BlockUser.call(form)
:ok
end

add_spam_detection_metadata!({
"blocked_at" => Time.current,
"spam_probability" => @probability
})
private

def create_user_moderation
@user.create_user_moderation
Rails.logger.info("User with id #{@user["id"]} was blocked for spam")
end

:ok
def register_justification!
UserBlock.create!(justification: reason, user: @user, blocking_user: @moderator)
end

def notify_user!
Decidim::BlockUserJob.perform_later(@user, reason)
end

def block!
Decidim.traceability.perform_action!(
"block",
@user,
@moderator,
extra: {
reportable_type: @user.class.name,
current_justification: reason
},
resource: {
# Make sure the action log entry gets the original user name instead
# of "Blocked user". Otherwise the log entries would show funny
# messages such as "Mr. Admin blocked user Blocked user"-
title: @user.name
}
) do
@user.blocked = true
@user.blocked_at = Time.current
@user.blocking = @current_blocking
@user.extended_data["user_name"] = @user.name
@user.name = "Blocked user"
@user.save!
end
end

def reason
"The user was blocked because of a high spam probability by Decidim spam detection bot with a probability of #{@probability}%"
end
end
end
Expand Down
50 changes: 32 additions & 18 deletions lib/decidim/spam_detection/report_spam_user_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,43 @@ class ReportSpamUserCommand < Decidim::SpamDetection::AbstractSpamUserCommand
prepend Decidim::SpamDetection::Command

def call
form = form(Decidim::ReportForm).from_params(
reason: "spam",
details: "The user was marked as spam by Decidim spam detection bot"
)
ActiveRecord::Base.transaction do
find_or_create_moderation!
create_report!
update_report_count!
add_spam_detection_metadata!({ "reported_at" => Time.current, "spam_probability" => @probability })
end

current_organization = @user.organization
moderator = @moderator
user = @user
Rails.logger.info("User with id #{@user.id} was reported for spam with a probability of #{@probability}%")

report = Decidim::CreateUserReport.new(form, user, moderator)
report.define_singleton_method(:current_organization) { current_organization }
report.define_singleton_method(:current_user) { moderator }
report.define_singleton_method(:reportable) { user }
report.call
:ok
end

add_spam_detection_metadata!({
"reported_at" => Time.current,
"spam_probability" => @probability
})
private

Rails.logger.info("User with id #{user.id} was reported for spam")
def reason
"spam"
end

:ok
def details
"The user was marked as spam by Decidim spam detection bot with a probability of #{@probability}%"
end

def find_or_create_moderation!
@moderation = UserModeration.find_or_create_by!(user: @user)
end

def create_report!
@report = UserReport.create!(
moderation: @moderation,
user: @moderator,
reason: reason,
details: details
)
end

def update_report_count!
@moderation.update!(report_count: @moderation.report_count + 1)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/decidim/spam_detection/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Decidim
# This holds the decidim-spam_detection version.
module SpamDetection
def self.version
"1.0.0"
"1.1.0"
end

def self.decidim_version
Expand Down
Loading