FEATURE: staff action logs when creating/updating/deleting badges

This commit is contained in:
Régis Hanol 2018-05-17 18:09:27 +02:00
parent 7ab7696c94
commit 53f8f6095d
6 changed files with 291 additions and 171 deletions

View File

@ -1,54 +1,58 @@
import { ajax } from 'discourse/lib/ajax'; import computed from "ember-addons/ember-computed-decorators";
import AdminUser from 'admin/models/admin-user'; import { ajax } from "discourse/lib/ajax";
import { escapeExpression } from 'discourse/lib/utilities'; import AdminUser from "admin/models/admin-user";
import { escapeExpression } from "discourse/lib/utilities";
function format(label, value, escape = true) {
return value ? `<b>${I18n.t(label)}</b>: ${escape ? escapeExpression(value) : value}` : "";
};
const StaffActionLog = Discourse.Model.extend({ const StaffActionLog = Discourse.Model.extend({
showFullDetails: false, showFullDetails: false,
actionName: function() { @computed("action_name")
return I18n.t("admin.logs.staff_actions.actions." + this.get('action_name')); actionName(actionName) {
}.property('action_name'), return I18n.t(`admin.logs.staff_actions.actions.${actionName}`);
formattedDetails: function() {
let formatted = "";
formatted += this.format('email', 'email');
formatted += this.format('admin.logs.ip_address', 'ip_address');
formatted += this.format('admin.logs.topic_id', 'topic_id');
formatted += this.format('admin.logs.post_id', 'post_id');
formatted += this.format('admin.logs.category_id', 'category_id');
if (!this.get('useCustomModalForDetails')) {
formatted += this.format('admin.logs.staff_actions.new_value', 'new_value');
formatted += this.format('admin.logs.staff_actions.previous_value', 'previous_value');
}
if (!this.get('useModalForDetails')) {
if (this.get('details')) formatted += escapeExpression(this.get('details')) + '<br/>';
}
return formatted;
}.property('ip_address', 'email', 'topic_id', 'post_id', 'category_id'),
format(label, propertyName) {
if (this.get(propertyName)) {
let value = escapeExpression(this.get(propertyName));
if (propertyName === 'post_id') {
value = `<a href data-link-post-id="${value}">${value}</a>`;
}
return `<b>${I18n.t(label)}:</b> ${value}<br/>`;
} else {
return '';
}
}, },
useModalForDetails: function() { @computed("email", "ip_address", "topic_id", "post_id", "category_id", "new_value", "previous_value", "details", "useCustomModalForDetails", "useModalForDetails")
return (this.get('details') && this.get('details').length > 100); formattedDetails(email, ipAddress, topicId, postId, categoryId, newValue, previousValue, details, useCustomModalForDetails, useModalForDetails) {
}.property('action_name'), const postLink = postId ? `<a href data-link-post-id="${postId}">${postId}</a>` : null;
useCustomModalForDetails: function() { let lines = [
return _.contains(['change_theme', 'delete_theme'], this.get('action_name')); format("email", email),
}.property('action_name') format("admin.logs.ip_address", ipAddress),
format("admin.logs.topic_id", topicId),
format("admin.logs.post_id", postLink, false),
format("admin.logs.category_id", categoryId),
];
if (!useCustomModalForDetails) {
lines.push(format("admin.logs.staff_actions.new_value", newValue));
lines.push(format("admin.logs.staff_actions.previous_value", previousValue));
}
if (!useModalForDetails && details) {
lines = [...lines, ...escapeExpression(details).split("\n")];
}
const formatted = lines.filter(l => l.length > 0).join("<br/>");
return formatted.length > 0 ? formatted + "<br/>" : "";
},
@computed("details")
useModalForDetails(details) {
return details && details.length > 100;
},
@computed("action_name")
useCustomModalForDetails(actionName) {
return ["change_theme", "delete_theme"].includes(actionName);
}
}); });
StaffActionLog.reopenClass({ StaffActionLog.reopenClass({
create: function(attrs) { create(attrs) {
attrs = attrs || {}; attrs = attrs || {};
if (attrs.acting_user) { if (attrs.acting_user) {
@ -60,13 +64,11 @@ StaffActionLog.reopenClass({
return this._super(attrs); return this._super(attrs);
}, },
findAll: function(filters) { findAll(data) {
return ajax("/admin/logs/staff_action_logs.json", { data: filters }).then((data) => { return ajax("/admin/logs/staff_action_logs.json", { data }).then(result => {
return { return {
staff_action_logs: data.staff_action_logs.map(function(s) { staff_action_logs: result.staff_action_logs.map(s => StaffActionLog.create(s)),
return StaffActionLog.create(s); user_history_actions: result.user_history_actions
}),
user_history_actions: data.user_history_actions
}; };
}); });
} }

View File

@ -15,10 +15,8 @@ class Admin::BadgesController < Admin::AdminController
end end
def preview def preview
unless SiteSetting.enable_badge_sql unless SiteSetting.enable_badge_sql
render json: "preview not allowed", status: 403 return render json: "preview not allowed", status: 403
return
end end
render json: BadgeGranter.preview(params[:sql], render json: BadgeGranter.preview(params[:sql],
@ -39,13 +37,12 @@ class Admin::BadgesController < Admin::AdminController
end end
def save_badge_groupings def save_badge_groupings
badge_groupings = BadgeGrouping.all.order(:position).to_a badge_groupings = BadgeGrouping.all.order(:position).to_a
ids = params[:ids].map(&:to_i) ids = params[:ids].map(&:to_i)
params[:names].each_with_index do |name, index| params[:names].each_with_index do |name, index|
id = ids[index].to_i id = ids[index].to_i
group = badge_groupings.find { |b| b.id == id } || BadgeGrouping.new() group = badge_groupings.find { |b| b.id == id } || BadgeGrouping.new
group.name = name group.name = name
group.position = index group.position = index
group.save group.save
@ -66,24 +63,27 @@ class Admin::BadgesController < Admin::AdminController
if errors.present? if errors.present?
render_json_error errors render_json_error errors
else else
StaffActionLogger.new(current_user).log_badge_creation(badge)
render_serialized(badge, AdminBadgeSerializer, root: "badge") render_serialized(badge, AdminBadgeSerializer, root: "badge")
end end
end end
def update def update
badge = find_badge badge = find_badge
errors = update_badge_from_params(badge) errors = update_badge_from_params(badge)
if errors.present? if errors.present?
render_json_error errors render_json_error errors
else else
StaffActionLogger.new(current_user).log_badge_change(badge)
render_serialized(badge, AdminBadgeSerializer, root: "badge") render_serialized(badge, AdminBadgeSerializer, root: "badge")
end end
end end
def destroy def destroy
find_badge.destroy badge = find_badge
StaffActionLogger.new(current_user).log_badge_deletion(badge)
badge.destroy
render body: nil render body: nil
end end

View File

@ -72,7 +72,10 @@ class UserHistory < ActiveRecord::Base
post_edit: 53, post_edit: 53,
topic_published: 54, topic_published: 54,
recover_topic: 55, recover_topic: 55,
post_approved: 56 post_approved: 56,
create_badge: 57,
change_badge: 58,
delete_badge: 59,
) )
end end
@ -123,7 +126,10 @@ class UserHistory < ActiveRecord::Base
:post_edit, :post_edit,
:topic_published, :topic_published,
:recover_topic, :recover_topic,
:post_approved :post_approved,
:create_badge,
:change_badge,
:delete_badge,
] ]
end end

View File

@ -12,11 +12,16 @@ class StaffActionLogger
raise Discourse::InvalidParameters.new(:admin) unless @admin && @admin.is_a?(User) raise Discourse::InvalidParameters.new(:admin) unless @admin && @admin.is_a?(User)
end end
USER_FIELDS ||= %i{id username name created_at trust_level last_seen_at last_emailed_at}
def log_user_deletion(deleted_user, opts = {}) def log_user_deletion(deleted_user, opts = {})
raise Discourse::InvalidParameters.new(:deleted_user) unless deleted_user && deleted_user.is_a?(User) raise Discourse::InvalidParameters.new(:deleted_user) unless deleted_user && deleted_user.is_a?(User)
UserHistory.create(params(opts).merge(action: UserHistory.actions[:delete_user], details = USER_FIELDS.map { |x| "#{x}: #{deleted_user.send(x)}" }.join("\n")
ip_address: deleted_user.ip_address.to_s, UserHistory.create!(params(opts).merge(
details: [:id, :username, :name, :created_at, :trust_level, :last_seen_at, :last_emailed_at].map { |x| "#{x}: #{deleted_user.send(x)}" }.join("\n"))) action: UserHistory.actions[:delete_user],
ip_address: deleted_user.ip_address.to_s,
details: details
))
end end
def log_custom(custom_type, details = nil) def log_custom(custom_type, details = nil)
@ -33,7 +38,7 @@ class StaffActionLogger
attrs[:action] = UserHistory.actions[:custom_staff] attrs[:action] = UserHistory.actions[:custom_staff]
attrs[:custom_type] = custom_type attrs[:custom_type] = custom_type
UserHistory.create(attrs) UserHistory.create!(attrs)
end end
def log_post_deletion(deleted_post, opts = {}) def log_post_deletion(deleted_post, opts = {})
@ -54,9 +59,11 @@ class StaffActionLogger
"raw: #{deleted_post.raw}" "raw: #{deleted_post.raw}"
] ]
UserHistory.create(params(opts).merge(action: UserHistory.actions[:delete_post], UserHistory.create!(params(opts).merge(
post_id: deleted_post.id, action: UserHistory.actions[:delete_post],
details: details.join("\n"))) post_id: deleted_post.id,
details: details.join("\n")
))
end end
def log_topic_delete_recover(topic, action = "delete_topic", opts = {}) def log_topic_delete_recover(topic, action = "delete_topic", opts = {})
@ -75,24 +82,31 @@ class StaffActionLogger
details << "raw: #{first_post.raw}" details << "raw: #{first_post.raw}"
end end
UserHistory.create(params(opts).merge(action: UserHistory.actions[action.to_sym], UserHistory.create!(params(opts).merge(
topic_id: topic.id, action: UserHistory.actions[action.to_sym],
details: details.join("\n"))) topic_id: topic.id,
details: details.join("\n")
))
end end
def log_trust_level_change(user, old_trust_level, new_trust_level, opts = {}) def log_trust_level_change(user, old_trust_level, new_trust_level, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user && user.is_a?(User) raise Discourse::InvalidParameters.new(:user) unless user && user.is_a?(User)
raise Discourse::InvalidParameters.new(:old_trust_level) unless TrustLevel.valid? old_trust_level raise Discourse::InvalidParameters.new(:old_trust_level) unless TrustLevel.valid? old_trust_level
raise Discourse::InvalidParameters.new(:new_trust_level) unless TrustLevel.valid? new_trust_level raise Discourse::InvalidParameters.new(:new_trust_level) unless TrustLevel.valid? new_trust_level
UserHistory.create!(params(opts).merge(action: UserHistory.actions[:change_trust_level], UserHistory.create!(params(opts).merge(
target_user_id: user.id, action: UserHistory.actions[:change_trust_level],
details: "old trust level: #{old_trust_level}\nnew trust level: #{new_trust_level}")) target_user_id: user.id,
details: "old trust level: #{old_trust_level}\nnew trust level: #{new_trust_level}"
))
end end
def log_lock_trust_level(user, opts = {}) def log_lock_trust_level(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user && user.is_a?(User) raise Discourse::InvalidParameters.new(:user) unless user && user.is_a?(User)
UserHistory.create!(params(opts).merge(action: UserHistory.actions[user.manual_locked_trust_level.nil? ? :unlock_trust_level : :lock_trust_level], action = UserHistory.actions[user.manual_locked_trust_level.nil? ? :unlock_trust_level : :lock_trust_level]
target_user_id: user.id)) UserHistory.create!(params(opts).merge(
action: action,
target_user_id: user.id
))
end end
def log_topic_published(topic, opts = {}) def log_topic_published(topic, opts = {})
@ -122,10 +136,12 @@ class StaffActionLogger
def log_site_setting_change(setting_name, previous_value, new_value, opts = {}) def log_site_setting_change(setting_name, previous_value, new_value, opts = {})
raise Discourse::InvalidParameters.new(:setting_name) unless setting_name.present? && SiteSetting.respond_to?(setting_name) raise Discourse::InvalidParameters.new(:setting_name) unless setting_name.present? && SiteSetting.respond_to?(setting_name)
UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_site_setting], UserHistory.create!(params(opts).merge(
subject: setting_name, action: UserHistory.actions[:change_site_setting],
previous_value: previous_value, subject: setting_name,
new_value: new_value)) previous_value: previous_value,
new_value: new_value
))
end end
def theme_json(theme) def theme_json(theme)
@ -157,41 +173,51 @@ class StaffActionLogger
old_json, new_json = strip_duplicates(old_json, new_json) old_json, new_json = strip_duplicates(old_json, new_json)
UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_theme], UserHistory.create!(params(opts).merge(
subject: new_theme.name, action: UserHistory.actions[:change_theme],
previous_value: old_json, subject: new_theme.name,
new_value: new_json)) previous_value: old_json,
new_value: new_json
))
end end
def log_theme_destroy(theme, opts = {}) def log_theme_destroy(theme, opts = {})
raise Discourse::InvalidParameters.new(:theme) unless theme raise Discourse::InvalidParameters.new(:theme) unless theme
UserHistory.create(params(opts).merge(action: UserHistory.actions[:delete_theme], UserHistory.create!(params(opts).merge(
subject: theme.name, action: UserHistory.actions[:delete_theme],
previous_value: theme_json(theme))) subject: theme.name,
previous_value: theme_json(theme)
))
end end
def log_site_text_change(subject, new_text = nil, old_text = nil, opts = {}) def log_site_text_change(subject, new_text = nil, old_text = nil, opts = {})
raise Discourse::InvalidParameters.new(:subject) unless subject.present? raise Discourse::InvalidParameters.new(:subject) unless subject.present?
UserHistory.create!(params(opts).merge(action: UserHistory.actions[:change_site_text], UserHistory.create!(params(opts).merge(
subject: subject, action: UserHistory.actions[:change_site_text],
previous_value: old_text, subject: subject,
new_value: new_text)) previous_value: old_text,
new_value: new_text
))
end end
def log_username_change(user, old_username, new_username, opts = {}) def log_username_change(user, old_username, new_username, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_username], UserHistory.create!(params(opts).merge(
target_user_id: user.id, action: UserHistory.actions[:change_username],
previous_value: old_username, target_user_id: user.id,
new_value: new_username)) previous_value: old_username,
new_value: new_username
))
end end
def log_name_change(user_id, old_name, new_name, opts = {}) def log_name_change(user_id, old_name, new_name, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user_id raise Discourse::InvalidParameters.new(:user) unless user_id
UserHistory.create(params(opts).merge(action: UserHistory.actions[:change_name], UserHistory.create!(params(opts).merge(
target_user_id: user_id, action: UserHistory.actions[:change_name],
previous_value: old_name, target_user_id: user_id,
new_value: new_name)) previous_value: old_name,
new_value: new_name
))
end end
def log_user_suspend(user, reason, opts = {}) def log_user_suspend(user, reason, opts = {})
@ -205,50 +231,96 @@ class StaffActionLogger
details: details details: details
) )
args[:post_id] = opts[:post_id] if opts[:post_id] args[:post_id] = opts[:post_id] if opts[:post_id]
UserHistory.create(args) UserHistory.create!(args)
end end
def log_user_unsuspend(user, opts = {}) def log_user_unsuspend(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:unsuspend_user], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:unsuspend_user],
target_user_id: user.id
))
end
BADGE_FIELDS ||= %i{id name description long_description icon image badge_type_id
badge_grouping_id query allow_title multiple_grant listable target_posts
enabled auto_revoke show_posts system}
def log_badge_creation(badge)
raise Discourse::InvalidParameters.new(:badge) unless badge
details = BADGE_FIELDS.map { |f| [f, badge.send(f)] }.select { |f, v| v.present? }.map { |f, v| "#{f}: #{v}" }
UserHistory.create!(params.merge(
action: UserHistory.actions[:create_badge],
details: details.join("\n")
))
end
def log_badge_change(badge)
raise Discourse::InvalidParameters.new(:badge) unless badge
details = ["id: #{badge.id}"]
badge.previous_changes.each { |f, values| details << "#{f}: #{values[1]}" if BADGE_FIELDS.include?(f.to_sym) }
UserHistory.create!(params.merge(
action: UserHistory.actions[:change_badge],
details: details.join("\n")
))
end
def log_badge_deletion(badge)
raise Discourse::InvalidParameters.new(:badge) unless badge
details = BADGE_FIELDS.map { |f| [f, badge.send(f)] }.select { |f, v| v.present? }.map { |f, v| "#{f}: #{v}" }
UserHistory.create!(params.merge(
action: UserHistory.actions[:delete_badge],
details: details.join("\n")
))
end end
def log_badge_grant(user_badge, opts = {}) def log_badge_grant(user_badge, opts = {})
raise Discourse::InvalidParameters.new(:user_badge) unless user_badge raise Discourse::InvalidParameters.new(:user_badge) unless user_badge
UserHistory.create(params(opts).merge(action: UserHistory.actions[:grant_badge], UserHistory.create!(params(opts).merge(
target_user_id: user_badge.user_id, action: UserHistory.actions[:grant_badge],
details: user_badge.badge.name)) target_user_id: user_badge.user_id,
details: user_badge.badge.name
))
end end
def log_badge_revoke(user_badge, opts = {}) def log_badge_revoke(user_badge, opts = {})
raise Discourse::InvalidParameters.new(:user_badge) unless user_badge raise Discourse::InvalidParameters.new(:user_badge) unless user_badge
UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_badge], UserHistory.create!(params(opts).merge(
target_user_id: user_badge.user_id, action: UserHistory.actions[:revoke_badge],
details: user_badge.badge.name)) target_user_id: user_badge.user_id,
details: user_badge.badge.name
))
end end
def log_check_email(user, opts = {}) def log_check_email(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:check_email], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:check_email],
target_user_id: user.id
))
end end
def log_show_emails(users, opts = {}) def log_show_emails(users, opts = {})
return if users.blank? return if users.blank?
UserHistory.create(params(opts).merge(action: UserHistory.actions[:check_email], UserHistory.create!(params(opts).merge(
details: users.map { |u| "[#{u.id}] #{u.username}" }.join("\n"))) action: UserHistory.actions[:check_email],
details: users.map { |u| "[#{u.id}] #{u.username}" }.join("\n")
))
end end
def log_impersonate(user, opts = {}) def log_impersonate(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:impersonate], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:impersonate],
target_user_id: user.id
))
end end
def log_roll_up(subnets, opts = {}) def log_roll_up(subnets, opts = {})
UserHistory.create(params(opts).merge(action: UserHistory.actions[:roll_up], UserHistory.create!(params(opts).merge(
details: subnets.join(", "))) action: UserHistory.actions[:roll_up],
details: subnets.join(", ")
))
end end
def log_category_settings_change(category, category_params, old_permissions = nil) def log_category_settings_change(category, category_params, old_permissions = nil)
@ -261,12 +333,14 @@ class StaffActionLogger
end end
changed_attributes.each do |key, value| changed_attributes.each do |key, value|
UserHistory.create(params.merge(action: UserHistory.actions[:change_category_settings], UserHistory.create!(params.merge(
category_id: category.id, action: UserHistory.actions[:change_category_settings],
context: category.url, category_id: category.id,
subject: key, context: category.url,
previous_value: value[0], subject: key,
new_value: value[1])) previous_value: value[0],
new_value: value[1]
))
end end
end end
@ -283,10 +357,12 @@ class StaffActionLogger
details << "parent_category: #{parent_category.name}" details << "parent_category: #{parent_category.name}"
end end
UserHistory.create(params.merge(action: UserHistory.actions[:delete_category], UserHistory.create!(params.merge(
category_id: category.id, action: UserHistory.actions[:delete_category],
details: details.join("\n"), category_id: category.id,
context: category.url)) details: details.join("\n"),
context: category.url
))
end end
def log_category_creation(category) def log_category_creation(category)
@ -297,10 +373,12 @@ class StaffActionLogger
"name: #{category.name}" "name: #{category.name}"
] ]
UserHistory.create(params.merge(action: UserHistory.actions[:create_category], UserHistory.create!(params.merge(
details: details.join("\n"), action: UserHistory.actions[:create_category],
category_id: category.id, details: details.join("\n"),
context: category.url)) category_id: category.id,
context: category.url
))
end end
def log_silence_user(user, opts = {}) def log_silence_user(user, opts = {})
@ -313,109 +391,139 @@ class StaffActionLogger
) )
create_args[:post_id] = opts[:post_id] if opts[:post_id] create_args[:post_id] = opts[:post_id] if opts[:post_id]
UserHistory.create(create_args) UserHistory.create!(create_args)
end end
def log_unsilence_user(user, opts = {}) def log_unsilence_user(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:unsilence_user], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:unsilence_user],
target_user_id: user.id
))
end end
def log_disable_second_factor_auth(user, opts = {}) def log_disable_second_factor_auth(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:disabled_second_factor], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:disabled_second_factor],
target_user_id: user.id
))
end end
def log_grant_admin(user, opts = {}) def log_grant_admin(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:grant_admin], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:grant_admin],
target_user_id: user.id
))
end end
def log_revoke_admin(user, opts = {}) def log_revoke_admin(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_admin], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:revoke_admin],
target_user_id: user.id
))
end end
def log_grant_moderation(user, opts = {}) def log_grant_moderation(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:grant_moderation], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:grant_moderation],
target_user_id: user.id
))
end end
def log_revoke_moderation(user, opts = {}) def log_revoke_moderation(user, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_moderation], UserHistory.create!(params(opts).merge(
target_user_id: user.id)) action: UserHistory.actions[:revoke_moderation],
target_user_id: user.id
))
end end
def log_backup_create(opts = {}) def log_backup_create(opts = {})
UserHistory.create(params(opts).merge(action: UserHistory.actions[:backup_create], UserHistory.create!(params(opts).merge(
ip_address: @admin.ip_address.to_s)) action: UserHistory.actions[:backup_create],
ip_address: @admin.ip_address.to_s
))
end end
def log_backup_download(backup, opts = {}) def log_backup_download(backup, opts = {})
raise Discourse::InvalidParameters.new(:backup) unless backup raise Discourse::InvalidParameters.new(:backup) unless backup
UserHistory.create(params(opts).merge(action: UserHistory.actions[:backup_download], UserHistory.create!(params(opts).merge(
ip_address: @admin.ip_address.to_s, action: UserHistory.actions[:backup_download],
details: backup.filename)) ip_address: @admin.ip_address.to_s,
details: backup.filename
))
end end
def log_backup_destroy(backup, opts = {}) def log_backup_destroy(backup, opts = {})
raise Discourse::InvalidParameters.new(:backup) unless backup raise Discourse::InvalidParameters.new(:backup) unless backup
UserHistory.create(params(opts).merge(action: UserHistory.actions[:backup_destroy], UserHistory.create!(params(opts).merge(
ip_address: @admin.ip_address.to_s, action: UserHistory.actions[:backup_destroy],
details: backup.filename)) ip_address: @admin.ip_address.to_s,
details: backup.filename
))
end end
def log_revoke_email(user, reason, opts = {}) def log_revoke_email(user, reason, opts = {})
UserHistory.create(params(opts).merge(action: UserHistory.actions[:revoke_email], UserHistory.create!(params(opts).merge(
target_user_id: user.id, action: UserHistory.actions[:revoke_email],
details: reason)) target_user_id: user.id,
details: reason
))
end end
def log_user_deactivate(user, reason, opts = {}) def log_user_deactivate(user, reason, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:deactivate_user], UserHistory.create!(params(opts).merge(
target_user_id: user.id, action: UserHistory.actions[:deactivate_user],
details: reason)) target_user_id: user.id,
details: reason
))
end end
def log_user_activate(user, reason, opts = {}) def log_user_activate(user, reason, opts = {})
raise Discourse::InvalidParameters.new(:user) unless user raise Discourse::InvalidParameters.new(:user) unless user
UserHistory.create(params(opts).merge(action: UserHistory.actions[:activate_user], UserHistory.create!(params(opts).merge(
target_user_id: user.id, action: UserHistory.actions[:activate_user],
details: reason)) target_user_id: user.id,
details: reason
))
end end
def log_wizard_step(step, opts = {}) def log_wizard_step(step, opts = {})
raise Discourse::InvalidParameters.new(:step) unless step raise Discourse::InvalidParameters.new(:step) unless step
UserHistory.create(params(opts).merge(action: UserHistory.actions[:wizard_step], UserHistory.create!(params(opts).merge(
context: step.id)) action: UserHistory.actions[:wizard_step],
context: step.id
))
end end
def log_change_readonly_mode(state) def log_change_readonly_mode(state)
UserHistory.create(params.merge(action: UserHistory.actions[:change_readonly_mode], UserHistory.create!(params.merge(
previous_value: !state, action: UserHistory.actions[:change_readonly_mode],
new_value: state)) previous_value: !state,
new_value: state
))
end end
def log_check_personal_message(topic, opts = {}) def log_check_personal_message(topic, opts = {})
raise Discourse::InvalidParameters.new(:topic) unless topic && topic.is_a?(Topic) raise Discourse::InvalidParameters.new(:topic) unless topic && topic.is_a?(Topic)
UserHistory.create(params(opts).merge(action: UserHistory.actions[:check_personal_message], UserHistory.create!(params(opts).merge(
topic_id: topic.id, action: UserHistory.actions[:check_personal_message],
context: topic.relative_url)) topic_id: topic.id,
context: topic.relative_url
))
end end
def log_post_approved(post, opts = {}) def log_post_approved(post, opts = {})
raise Discourse::InvalidParameters.new(:post) unless post && post.is_a?(Post) raise Discourse::InvalidParameters.new(:post) unless post && post.is_a?(Post)
UserHistory.create!(params(opts).merge( UserHistory.create!(params(opts).merge(
action: UserHistory.actions[:post_approved], action: UserHistory.actions[:post_approved],
post_id: post.id) post_id: post.id
) ))
end end
private private

View File

@ -3401,6 +3401,9 @@ en:
disabled_second_factor: "disable Two Factor Authentication" disabled_second_factor: "disable Two Factor Authentication"
topic_published: "topic published" topic_published: "topic published"
post_approved: "post approved" post_approved: "post approved"
create_badge: "create badge"
change_badge: "change badge"
delete_badge: "delete badge"
screened_emails: screened_emails:
title: "Screened Emails" title: "Screened Emails"
description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed." description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed."

View File

@ -48,6 +48,8 @@ describe Admin::BadgesController do
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json["badge"]["name"]).to eq('test') expect(json["badge"]["name"]).to eq('test')
expect(json["badge"]["query"]).to eq('select 1 as user_id, null as granted_at') expect(json["badge"]["query"]).to eq('select 1 as user_id, null as granted_at')
expect(UserHistory.where(acting_user_id: user.id, action: UserHistory.actions[:create_badge]).exists?).to eq(true)
end end
end end
@ -83,14 +85,11 @@ describe Admin::BadgesController do
end end
context '.destroy' do context '.destroy' do
it 'returns success' do
delete :destroy, params: { id: badge.id }, format: :json
expect(response).to be_success
end
it 'deletes the badge' do it 'deletes the badge' do
delete :destroy, params: { id: badge.id }, format: :json delete :destroy, params: { id: badge.id }, format: :json
expect(Badge.where(id: badge.id).count).to eq(0) expect(response).to be_success
expect(Badge.where(id: badge.id).exists?).to eq(false)
expect(UserHistory.where(acting_user_id: user.id, action: UserHistory.actions[:delete_badge]).exists?).to eq(true)
end end
end end
@ -108,6 +107,8 @@ describe Admin::BadgesController do
expect(response).to be_success expect(response).to be_success
editor_badge.reload editor_badge.reload
expect(editor_badge.name).to eq(editor_badge_name) expect(editor_badge.name).to eq(editor_badge_name)
expect(UserHistory.where(acting_user_id: user.id, action: UserHistory.actions[:change_badge]).exists?).to eq(true)
end end
it 'does not allow query updates if badge_sql is disabled' do it 'does not allow query updates if badge_sql is disabled' do