Merge branch 'main' into glitch-soc/merge-upstream
Conflicts: - `db/schema.rb`: Conflict due to glitch-soc adding the `content_type` column on status edits and thus having a different schema version number. Solved by taking upstream's schema version number, as it is higher than glitch-soc's.
This commit is contained in:
@ -274,6 +274,10 @@ class Account < ApplicationRecord
|
||||
true
|
||||
end
|
||||
|
||||
def previous_strikes_count
|
||||
strikes.where(overruled_at: nil).count
|
||||
end
|
||||
|
||||
def keypair
|
||||
@keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
|
||||
end
|
||||
|
@ -24,6 +24,8 @@ class AccountFilter
|
||||
scope = Account.includes(:account_stat, user: [:ips, :invite_request]).without_instance_actor.reorder(nil)
|
||||
|
||||
params.each do |key, value|
|
||||
next if key.to_s == 'page'
|
||||
|
||||
scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
|
||||
end
|
||||
|
||||
@ -49,7 +51,7 @@ class AccountFilter
|
||||
when 'email'
|
||||
accounts_with_users.merge(User.matches_email(value))
|
||||
when 'ip'
|
||||
valid_ip?(value) ? accounts_with_users.merge(User.matches_ip(value)) : Account.none
|
||||
valid_ip?(value) ? accounts_with_users.merge(User.matches_ip(value).group('users.id, accounts.id')) : Account.none
|
||||
when 'invited_by'
|
||||
invited_by_scope(value)
|
||||
when 'order'
|
||||
|
@ -12,6 +12,7 @@
|
||||
# updated_at :datetime not null
|
||||
# report_id :bigint(8)
|
||||
# status_ids :string is an Array
|
||||
# overruled_at :datetime
|
||||
#
|
||||
|
||||
class AccountWarning < ApplicationRecord
|
||||
@ -28,12 +29,17 @@ class AccountWarning < ApplicationRecord
|
||||
belongs_to :target_account, class_name: 'Account', inverse_of: :strikes
|
||||
belongs_to :report, optional: true
|
||||
|
||||
has_one :appeal, dependent: :destroy
|
||||
has_one :appeal, dependent: :destroy, inverse_of: :strike
|
||||
|
||||
scope :latest, -> { order(id: :desc) }
|
||||
scope :custom, -> { where.not(text: '') }
|
||||
scope :active, -> { where(overruled_at: nil).or(where('account_warnings.overruled_at >= ?', 30.days.ago)) }
|
||||
|
||||
def statuses
|
||||
Status.with_discarded.where(id: status_ids || [])
|
||||
end
|
||||
|
||||
def overruled?
|
||||
overruled_at.present?
|
||||
end
|
||||
end
|
||||
|
@ -8,6 +8,8 @@ class Admin::ActionLogFilter
|
||||
).freeze
|
||||
|
||||
ACTION_TYPE_MAP = {
|
||||
approve_appeal: { target_type: 'Appeal', action: 'approve' }.freeze,
|
||||
reject_appeal: { target_type: 'Appeal', action: 'reject' }.freeze,
|
||||
assigned_to_self_report: { target_type: 'Report', action: 'assigned_to_self' }.freeze,
|
||||
change_email_user: { target_type: 'User', action: 'change_email' }.freeze,
|
||||
confirm_user: { target_type: 'User', action: 'confirm' }.freeze,
|
||||
|
49
app/models/admin/appeal_filter.rb
Normal file
49
app/models/admin/appeal_filter.rb
Normal file
@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::AppealFilter
|
||||
KEYS = %i(
|
||||
status
|
||||
).freeze
|
||||
|
||||
attr_reader :params
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def results
|
||||
scope = Appeal.order(id: :desc)
|
||||
|
||||
params.each do |key, value|
|
||||
next if %w(page).include?(key.to_s)
|
||||
|
||||
scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
|
||||
end
|
||||
|
||||
scope
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scope_for(key, value)
|
||||
case key.to_s
|
||||
when 'status'
|
||||
status_scope(value)
|
||||
else
|
||||
raise "Unknown filter: #{key}"
|
||||
end
|
||||
end
|
||||
|
||||
def status_scope(value)
|
||||
case value
|
||||
when 'approved'
|
||||
Appeal.approved
|
||||
when 'rejected'
|
||||
Appeal.rejected
|
||||
when 'pending'
|
||||
Appeal.pending
|
||||
else
|
||||
raise "Unknown status: #{value}"
|
||||
end
|
||||
end
|
||||
end
|
@ -31,7 +31,7 @@ class Admin::StatusFilter
|
||||
def scope_for(key, value)
|
||||
case key.to_s
|
||||
when 'media'
|
||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
|
||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id).reorder('statuses.id desc')
|
||||
when 'id'
|
||||
Status.where(id: value)
|
||||
else
|
||||
|
60
app/models/appeal.rb
Normal file
60
app/models/appeal.rb
Normal file
@ -0,0 +1,60 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: appeals
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# account_warning_id :bigint(8) not null
|
||||
# text :text default(""), not null
|
||||
# approved_at :datetime
|
||||
# approved_by_account_id :bigint(8)
|
||||
# rejected_at :datetime
|
||||
# rejected_by_account_id :bigint(8)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class Appeal < ApplicationRecord
|
||||
MAX_STRIKE_AGE = 20.days
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :strike, class_name: 'AccountWarning', foreign_key: 'account_warning_id'
|
||||
belongs_to :approved_by_account, class_name: 'Account', optional: true
|
||||
belongs_to :rejected_by_account, class_name: 'Account', optional: true
|
||||
|
||||
validates :text, presence: true, length: { maximum: 2_000 }
|
||||
validates :account_warning_id, uniqueness: true
|
||||
|
||||
validate :validate_time_frame, on: :create
|
||||
|
||||
scope :approved, -> { where.not(approved_at: nil) }
|
||||
scope :rejected, -> { where.not(rejected_at: nil) }
|
||||
scope :pending, -> { where(approved_at: nil, rejected_at: nil) }
|
||||
|
||||
def pending?
|
||||
!approved? && !rejected?
|
||||
end
|
||||
|
||||
def approved?
|
||||
approved_at.present?
|
||||
end
|
||||
|
||||
def rejected?
|
||||
rejected_at.present?
|
||||
end
|
||||
|
||||
def approve!(current_account)
|
||||
update!(approved_at: Time.now.utc, approved_by_account: current_account)
|
||||
end
|
||||
|
||||
def reject!(current_account)
|
||||
update!(rejected_at: Time.now.utc, rejected_by_account: current_account)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_time_frame
|
||||
errors.add(:base, I18n.t('strikes.errors.too_late')) if strike.created_at < MAX_STRIKE_AGE.ago
|
||||
end
|
||||
end
|
@ -111,7 +111,7 @@ class User < ApplicationRecord
|
||||
scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
|
||||
scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended_at: nil }) }
|
||||
scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) }
|
||||
scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value) }
|
||||
scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value).group('users.id') }
|
||||
scope :emailable, -> { confirmed.enabled.joins(:account).merge(Account.searchable) }
|
||||
|
||||
before_validation :sanitize_languages
|
||||
@ -265,6 +265,10 @@ class User < ApplicationRecord
|
||||
settings.notification_emails['pending_account']
|
||||
end
|
||||
|
||||
def allows_appeal_emails?
|
||||
settings.notification_emails['appeal']
|
||||
end
|
||||
|
||||
def allows_trending_tag_emails?
|
||||
settings.notification_emails['trending_tag']
|
||||
end
|
||||
|
Reference in New Issue
Block a user