eBooru/app/models/bulk_update_request.rb

225 lines
6.0 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
class BulkUpdateRequest < ApplicationRecord
attr_accessor :reason, :skip_forum, :should_validate
2014-06-16 20:29:27 -04:00
2014-06-12 23:12:09 -04:00
belongs_to :user
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
belongs_to :forum_topic, optional: true
belongs_to :forum_post, optional: true
belongs_to :approver, optional: true, class_name: "User"
2014-06-12 23:12:09 -04:00
2019-09-05 08:59:51 -04:00
validates :user, presence: true
validates :script, presence: true
validates :title, presence: { if: ->(rec) {rec.forum_topic_id.blank?} }
validates :status, inclusion: { :in => %w(pending approved rejected) }
2014-06-17 13:19:40 -04:00
validate :script_formatted_correctly
validate :forum_topic_id_not_invalid
2020-07-13 01:53:02 -04:00
validate :validate_script, on: :create
validate :check_validate_script, on: :update
validates :reason, length: { minimum: 5 }, on: :create, unless: :skip_forum
before_validation :initialize_attributes, on: :create
2015-04-21 20:22:16 -04:00
before_validation :normalize_text
2014-06-16 20:29:27 -04:00
after_create :create_forum_topic
2014-06-12 23:12:09 -04:00
scope :pending_first, -> { order(Arel.sql("(case status when 'pending' then 0 when 'approved' then 1 else 2 end)")) }
scope :pending, -> {where(status: "pending")}
2021-07-19 11:48:23 -04:00
module ApiMethods
def hidden_attributes
super + [:user_ip_addr]
end
end
2014-06-17 13:20:29 -04:00
module SearchMethods
def for_creator(id)
where("user_id = ?", id)
end
def default_order
pending_first.order(id: :desc)
end
def search(params)
q = super
2014-06-17 13:20:29 -04:00
q = q.where_user(:user_id, :user, params)
q = q.where_user(:approver_id, :approver, params)
if params[:forum_topic_id].present?
q = q.where(forum_topic_id: params[:forum_topic_id].split(",").map(&:to_i))
end
if params[:forum_post_id].present?
q = q.where(forum_post_id: params[:forum_post_id].split(",").map(&:to_i))
end
if params[:status].present?
q = q.where(status: params[:status].split(","))
end
q = q.attribute_matches(:title, params[:title_matches])
q = q.attribute_matches(:script, params[:script_matches])
params[:order] ||= "status_desc"
case params[:order]
when "updated_at_desc"
q = q.order(updated_at: :desc)
when "updated_at_asc"
q = q.order(updated_at: :asc)
else
2023-07-07 08:32:57 -04:00
q = q.apply_basic_order(params)
end
2014-06-17 13:20:29 -04:00
q
end
end
module ApprovalMethods
def forum_updater
@forum_updater ||= begin
post = if forum_topic
forum_post || forum_topic.posts.first
else
nil
end
ForumUpdater.new(
forum_topic,
forum_post: post,
expected_title: title,
skip_update: !TagRelationship::SUPPORT_HARD_CODED
)
end
end
2014-06-19 03:06:36 -04:00
def approve!(approver)
transaction do
CurrentUser.scoped(approver) do
BulkUpdateRequestImporter.new(script, forum_topic_id, user_id, user_ip_addr).process!
update(status: "approved", approver: CurrentUser.user)
2020-03-14 22:51:41 -04:00
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post&.id}) has been approved by @#{approver.name}.", "APPROVED")
end
end
2022-12-26 14:21:33 -05:00
rescue BulkUpdateRequestImporter::Error => x
self.approver = approver
CurrentUser.scoped(approver) do
2020-03-14 22:51:41 -04:00
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post&.id}) has failed: #{x.to_s}", "FAILED")
end
2021-02-07 21:56:22 -05:00
self.errors.add(:base, x.to_s)
end
def create_forum_topic
return if skip_forum
if forum_topic_id
forum_post = forum_topic.posts.create(body: reason_with_link)
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
update(forum_post_id: forum_post.id)
else
forum_topic = ForumTopic.create(title: title, category_id: Danbooru.config.alias_implication_forum_category, original_post_attributes: {body: reason_with_link})
Raise error on unpermitted params. Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
2018-04-02 13:51:26 -04:00
update(forum_topic_id: forum_topic.id, forum_post_id: forum_topic.posts.first.id)
end
end
def reject!(rejector = User.system)
transaction do
update(status: "rejected")
2019-11-09 13:54:33 -05:00
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post&.id}) has been rejected by @#{rejector.name}.", "REJECTED")
end
end
def bulk_update_request_link
%("bulk update request ##{id}":/bulk_update_requests/#{id})
end
end
module ValidationMethods
def script_formatted_correctly
2022-12-26 14:21:33 -05:00
BulkUpdateRequestImporter.tokenize(script)
return true
rescue StandardError => e
2021-02-07 21:56:22 -05:00
errors.add(:base, e.message)
return false
end
def forum_topic_id_not_invalid
if forum_topic_id && !forum_topic
2021-02-07 21:56:22 -05:00
errors.add(:base, "Forum topic ID is invalid")
end
end
2020-07-13 01:53:02 -04:00
def check_validate_script
validate_script if should_validate
end
def validate_script
errors, new_script = BulkUpdateRequestImporter.new(script, forum_topic_id).validate!(CurrentUser.user)
2022-04-09 07:43:51 -04:00
if errors.size > 0
errors.each { |err| self.errors.add(:base, err) }
end
self.script = new_script
2014-06-12 23:12:09 -04:00
errors.empty?
2022-12-26 14:21:33 -05:00
rescue BulkUpdateRequestImporter::Error => e
self.errors.add(:script, e)
end
end
extend SearchMethods
include ApprovalMethods
include ValidationMethods
2021-07-19 11:48:23 -04:00
include ApiMethods
concerning :EmbeddedText do
class_methods do
def embedded_pattern
/\[bur:(?<id>\d+)\]/m
end
end
end
2014-06-17 21:06:28 -04:00
def editable?(user)
2022-12-26 10:30:38 -05:00
is_pending? && (user_id == user.id || user.is_admin?)
2014-06-17 21:06:28 -04:00
end
def approvable?(user)
2024-03-03 06:04:56 -05:00
is_pending? && user.is_admin?
end
def rejectable?(user)
is_pending? && editable?(user)
end
2014-06-16 20:29:27 -04:00
def reason_with_link
"[bur:#{id}]\n\nReason: #{reason}"
end
2014-06-12 23:12:09 -04:00
def initialize_attributes
self.user_id = CurrentUser.user.id unless self.user_id
self.user_ip_addr = CurrentUser.ip_addr unless self.user_ip_addr
2014-06-12 23:12:09 -04:00
self.status = "pending"
end
2014-06-17 13:19:40 -04:00
2015-04-21 20:22:16 -04:00
def normalize_text
self.script = script.downcase
end
def skip_forum=(v)
@skip_forum = v.to_s.truthy?
end
2018-05-15 17:47:14 -04:00
def is_pending?
status == "pending"
end
def is_approved?
status == "approved"
end
def is_rejected?
status == "rejected"
end
def estimate_update_count
2022-12-26 14:21:33 -05:00
BulkUpdateRequestImporter.new(script, nil).estimate_update_count
end
2014-06-12 23:12:09 -04:00
end