mirror of
https://github.com/mastodon/mastodon.git
synced 2024-08-20 21:08:15 -07:00
Merge d1b6f1c531
into a50c8e951f
This commit is contained in:
commit
88232bc88c
24 changed files with 116 additions and 151 deletions
|
@ -57,11 +57,6 @@ Style/FormatStringToken:
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'lib/paperclip/color_extractor.rb'
|
- 'lib/paperclip/color_extractor.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
|
||||||
Style/GuardClause:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
Style/HashTransformValues:
|
Style/HashTransformValues:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|
|
@ -15,9 +15,9 @@ class ActivityPub::Activity::Block < ActivityPub::Activity
|
||||||
UnfollowService.new.call(target_account, @account) if target_account.following?(@account)
|
UnfollowService.new.call(target_account, @account) if target_account.following?(@account)
|
||||||
RejectFollowService.new.call(target_account, @account) if target_account.requested?(@account)
|
RejectFollowService.new.call(target_account, @account) if target_account.requested?(@account)
|
||||||
|
|
||||||
unless delete_arrived_first?(@json['id'])
|
return if delete_arrived_first?(@json['id'])
|
||||||
BlockWorker.perform_async(@account.id, target_account.id)
|
|
||||||
@account.block!(target_account, uri: @json['id'])
|
BlockWorker.perform_async(@account.id, target_account.id)
|
||||||
end
|
@account.block!(target_account, uri: @json['id'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -318,11 +318,9 @@ class Request
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if outer_e
|
raise outer_e if outer_e
|
||||||
raise outer_e
|
|
||||||
else
|
raise SocketError, "No address for #{host}"
|
||||||
raise SocketError, "No address for #{host}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
alias new open
|
alias new open
|
||||||
|
|
|
@ -58,13 +58,11 @@ class RequestPool
|
||||||
|
|
||||||
close
|
close
|
||||||
|
|
||||||
if @fresh || retries.positive?
|
raise if @fresh || retries.positive?
|
||||||
raise
|
|
||||||
else
|
@http_client = http_client
|
||||||
@http_client = http_client
|
retries += 1
|
||||||
retries += 1
|
retry
|
||||||
retry
|
|
||||||
end
|
|
||||||
rescue
|
rescue
|
||||||
# If this connection raises errors of any kind, it's
|
# If this connection raises errors of any kind, it's
|
||||||
# better if it gets reaped as soon as possible
|
# better if it gets reaped as soon as possible
|
||||||
|
|
|
@ -84,22 +84,18 @@ class Webfinger
|
||||||
|
|
||||||
def body_from_host_meta
|
def body_from_host_meta
|
||||||
host_meta_request.perform do |res|
|
host_meta_request.perform do |res|
|
||||||
if res.code == 200
|
raise Webfinger::Error, "Request for #{@uri} returned HTTP #{res.code}" unless res.code == 200
|
||||||
body_from_webfinger(url_from_template(res.body_with_limit), false)
|
|
||||||
else
|
body_from_webfinger(url_from_template(res.body_with_limit), false)
|
||||||
raise Webfinger::Error, "Request for #{@uri} returned HTTP #{res.code}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_from_template(str)
|
def url_from_template(str)
|
||||||
link = Nokogiri::XML(str).at_xpath('//xmlns:Link[@rel="lrdd"]')
|
link = Nokogiri::XML(str).at_xpath('//xmlns:Link[@rel="lrdd"]')
|
||||||
|
|
||||||
if link.present?
|
raise Webfinger::Error, "Request for #{@uri} returned host-meta without link to Webfinger" if link.blank?
|
||||||
link['template'].gsub('{uri}', @uri)
|
|
||||||
else
|
link['template'].gsub('{uri}', @uri)
|
||||||
raise Webfinger::Error, "Request for #{@uri} returned host-meta without link to Webfinger"
|
|
||||||
end
|
|
||||||
rescue Nokogiri::XML::XPath::SyntaxError
|
rescue Nokogiri::XML::XPath::SyntaxError
|
||||||
raise Webfinger::Error, "Invalid XML encountered in host-meta for #{@uri}"
|
raise Webfinger::Error, "Invalid XML encountered in host-meta for #{@uri}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,11 +54,9 @@ class WebfingerResource
|
||||||
end
|
end
|
||||||
|
|
||||||
def username_from_acct
|
def username_from_acct
|
||||||
if domain_matches_local?
|
raise ActiveRecord::RecordNotFound unless domain_matches_local?
|
||||||
local_username
|
|
||||||
else
|
local_username
|
||||||
raise ActiveRecord::RecordNotFound
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def split_acct
|
def split_acct
|
||||||
|
|
|
@ -38,10 +38,10 @@ module Account::Counters
|
||||||
result = updated_account_stat(key, value.to_i)
|
result = updated_account_stat(key, value.to_i)
|
||||||
|
|
||||||
# Reload account_stat if it was loaded, taking into account newly-created unsaved records
|
# Reload account_stat if it was loaded, taking into account newly-created unsaved records
|
||||||
if association(:account_stat).loaded?
|
return unless association(:account_stat).loaded?
|
||||||
account_stat.id = result.first['id'] if account_stat.new_record?
|
|
||||||
account_stat.reload
|
account_stat.id = result.first['id'] if account_stat.new_record?
|
||||||
end
|
account_stat.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_stat
|
def account_stat
|
||||||
|
|
|
@ -8,9 +8,9 @@ module User::LdapAuthenticable
|
||||||
ldap = Net::LDAP.new(ldap_options)
|
ldap = Net::LDAP.new(ldap_options)
|
||||||
filter = format(Devise.ldap_search_filter, uid: Devise.ldap_uid, mail: Devise.ldap_mail, email: Net::LDAP::Filter.escape(params[:email]))
|
filter = format(Devise.ldap_search_filter, uid: Devise.ldap_uid, mail: Devise.ldap_mail, email: Net::LDAP::Filter.escape(params[:email]))
|
||||||
|
|
||||||
if (user_info = ldap.bind_as(base: Devise.ldap_base, filter: filter, password: params[:password]))
|
return unless (user_info = ldap.bind_as(base: Devise.ldap_base, filter: filter, password: params[:password]))
|
||||||
ldap_get_user(user_info.first)
|
|
||||||
end
|
ldap_get_user(user_info.first)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ldap_get_user(attributes = {})
|
def ldap_get_user(attributes = {})
|
||||||
|
|
|
@ -178,9 +178,9 @@ class Tag < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_display_name_change
|
def validate_display_name_change
|
||||||
unless HashtagNormalizer.new.normalize(display_name).casecmp(name.mb_chars).zero?
|
return if HashtagNormalizer.new.normalize(display_name).casecmp(name.mb_chars).zero?
|
||||||
errors.add(:display_name,
|
|
||||||
I18n.t('tags.does_not_match_previous_name'))
|
errors.add(:display_name,
|
||||||
end
|
I18n.t('tags.does_not_match_previous_name'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -433,16 +433,16 @@ class User < ApplicationRecord
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
if new_user
|
return unless new_user
|
||||||
# Avoid extremely unlikely race condition when approving and confirming
|
|
||||||
# the user at the same time
|
|
||||||
reload unless approved?
|
|
||||||
|
|
||||||
if approved?
|
# Avoid extremely unlikely race condition when approving and confirming
|
||||||
prepare_new_user!
|
# the user at the same time
|
||||||
else
|
reload unless approved?
|
||||||
notify_staff_about_pending_account!
|
|
||||||
end
|
if approved?
|
||||||
|
prepare_new_user!
|
||||||
|
else
|
||||||
|
notify_staff_about_pending_account!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -139,10 +139,10 @@ class FanOutOnWriteService < BaseService
|
||||||
redis.publish('timeline:public', anonymous_payload)
|
redis.publish('timeline:public', anonymous_payload)
|
||||||
redis.publish(@status.local? ? 'timeline:public:local' : 'timeline:public:remote', anonymous_payload)
|
redis.publish(@status.local? ? 'timeline:public:local' : 'timeline:public:remote', anonymous_payload)
|
||||||
|
|
||||||
if @status.with_media?
|
return unless @status.with_media?
|
||||||
redis.publish('timeline:public:media', anonymous_payload)
|
|
||||||
redis.publish(@status.local? ? 'timeline:public:local:media' : 'timeline:public:remote:media', anonymous_payload)
|
redis.publish('timeline:public:media', anonymous_payload)
|
||||||
end
|
redis.publish(@status.local? ? 'timeline:public:local:media' : 'timeline:public:remote:media', anonymous_payload)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deliver_to_conversation!
|
def deliver_to_conversation!
|
||||||
|
|
|
@ -98,20 +98,18 @@ class PostStatusService < BaseService
|
||||||
def schedule_status!
|
def schedule_status!
|
||||||
status_for_validation = @account.statuses.build(status_attributes)
|
status_for_validation = @account.statuses.build(status_attributes)
|
||||||
|
|
||||||
if status_for_validation.valid?
|
raise ActiveRecord::RecordInvalid unless status_for_validation.valid?
|
||||||
# Marking the status as destroyed is necessary to prevent the status from being
|
|
||||||
# persisted when the associated media attachments get updated when creating the
|
|
||||||
# scheduled status.
|
|
||||||
status_for_validation.destroy
|
|
||||||
|
|
||||||
# The following transaction block is needed to wrap the UPDATEs to
|
# Marking the status as destroyed is necessary to prevent the status from being
|
||||||
# the media attachments when the scheduled status is created
|
# persisted when the associated media attachments get updated when creating the
|
||||||
|
# scheduled status.
|
||||||
|
status_for_validation.destroy
|
||||||
|
|
||||||
ApplicationRecord.transaction do
|
# The following transaction block is needed to wrap the UPDATEs to
|
||||||
@status = @account.scheduled_statuses.create!(scheduled_status_attributes)
|
# the media attachments when the scheduled status is created
|
||||||
end
|
|
||||||
else
|
ApplicationRecord.transaction do
|
||||||
raise ActiveRecord::RecordInvalid
|
@status = @account.scheduled_statuses.create!(scheduled_status_attributes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,10 @@ class ProcessHashtagsService < BaseService
|
||||||
|
|
||||||
removed_tags = @previous_tags - @current_tags
|
removed_tags = @previous_tags - @current_tags
|
||||||
|
|
||||||
unless removed_tags.empty?
|
return if removed_tags.empty?
|
||||||
@account.featured_tags.where(tag_id: removed_tags.map(&:id)).find_each do |featured_tag|
|
|
||||||
featured_tag.decrement(@status.id)
|
@account.featured_tags.where(tag_id: removed_tags.map(&:id)).find_each do |featured_tag|
|
||||||
end
|
featured_tag.decrement(@status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -123,11 +123,11 @@ class MoveWorker
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_account_note_if_needed!(account, id)
|
def add_account_note_if_needed!(account, id)
|
||||||
unless AccountNote.exists?(account: account, target_account: @target_account)
|
return if AccountNote.exists?(account: account, target_account: @target_account)
|
||||||
text = I18n.with_locale(account.user&.locale.presence || I18n.default_locale) do
|
|
||||||
I18n.t(id, acct: @source_account.acct)
|
text = I18n.with_locale(account.user&.locale.presence || I18n.default_locale) do
|
||||||
end
|
I18n.t(id, acct: @source_account.acct)
|
||||||
AccountNote.create!(account: account, target_account: @target_account, comment: text)
|
|
||||||
end
|
end
|
||||||
|
AccountNote.create!(account: account, target_account: @target_account, comment: text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,10 +20,7 @@ class RedownloadAvatarWorker
|
||||||
rescue Mastodon::UnexpectedResponseError => e
|
rescue Mastodon::UnexpectedResponseError => e
|
||||||
response = e.response
|
response = e.response
|
||||||
|
|
||||||
if response_error_unsalvageable?(response)
|
raise e unless response_error_unsalvageable?(response)
|
||||||
# Give up
|
# Give up
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,10 +20,7 @@ class RedownloadHeaderWorker
|
||||||
rescue Mastodon::UnexpectedResponseError => e
|
rescue Mastodon::UnexpectedResponseError => e
|
||||||
response = e.response
|
response = e.response
|
||||||
|
|
||||||
if response_error_unsalvageable?(response)
|
raise e unless response_error_unsalvageable?(response)
|
||||||
# Give up
|
# Give up
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,10 +20,7 @@ class RedownloadMediaWorker
|
||||||
rescue Mastodon::UnexpectedResponseError => e
|
rescue Mastodon::UnexpectedResponseError => e
|
||||||
response = e.response
|
response = e.response
|
||||||
|
|
||||||
if response_error_unsalvageable?(response)
|
raise e unless response_error_unsalvageable?(response)
|
||||||
# Give up
|
# Give up
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,10 +15,7 @@ class RemoteAccountRefreshWorker
|
||||||
rescue Mastodon::UnexpectedResponseError => e
|
rescue Mastodon::UnexpectedResponseError => e
|
||||||
response = e.response
|
response = e.response
|
||||||
|
|
||||||
if response_error_unsalvageable?(response)
|
raise e unless response_error_unsalvageable?(response)
|
||||||
# Give up
|
# Give up
|
||||||
else
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,11 +13,9 @@ module Devise
|
||||||
def authenticate!
|
def authenticate!
|
||||||
resource = mapping.to.authenticate_with_ldap(params[scope])
|
resource = mapping.to.authenticate_with_ldap(params[scope])
|
||||||
|
|
||||||
if resource && !resource.otp_required_for_login?
|
fail(:invalid) unless resource && !resource.otp_required_for_login? # rubocop:disable Style/SignalException -- method is from Warden::Strategies::Base
|
||||||
success!(resource)
|
|
||||||
else
|
success!(resource)
|
||||||
fail(:invalid) # rubocop:disable Style/SignalException -- method is from Warden::Strategies::Base
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -12,11 +12,9 @@ module Devise
|
||||||
def authenticate!
|
def authenticate!
|
||||||
resource = mapping.to.authenticate_with_pam(params[scope])
|
resource = mapping.to.authenticate_with_pam(params[scope])
|
||||||
|
|
||||||
if resource && !resource.otp_required_for_login?
|
fail(:invalid) unless resource && !resource.otp_required_for_login? # rubocop:disable Style/SignalException -- method is from Warden::Strategies::Base
|
||||||
success!(resource)
|
|
||||||
else
|
success!(resource)
|
||||||
fail(:invalid) # rubocop:disable Style/SignalException -- method is from Warden::Strategies::Base
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -320,10 +320,10 @@ module Mastodon::CLI
|
||||||
|
|
||||||
say("Visited #{processed} accounts, removed #{culled}#{dry_run_mode_suffix}", :green)
|
say("Visited #{processed} accounts, removed #{culled}#{dry_run_mode_suffix}", :green)
|
||||||
|
|
||||||
unless skip_domains.empty?
|
return if skip_domains.empty?
|
||||||
say('The following domains were not available during the check:', :yellow)
|
|
||||||
skip_domains.each { |domain| say(" #{domain}") }
|
say('The following domains were not available during the check:', :yellow)
|
||||||
end
|
skip_domains.each { |domain| say(" #{domain}") }
|
||||||
end
|
end
|
||||||
|
|
||||||
option :all, type: :boolean
|
option :all, type: :boolean
|
||||||
|
|
|
@ -146,18 +146,18 @@ module Mastodon::CLI
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if db_table_exists?(:severed_relationships)
|
return unless db_table_exists?(:severed_relationships)
|
||||||
SeveredRelationship.where(local_account_id: other_account.id).reorder(nil).find_each do |record|
|
|
||||||
record.update_attribute(:local_account_id, id)
|
|
||||||
rescue ActiveRecord::RecordNotUnique
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
SeveredRelationship.where(remote_account_id: other_account.id).reorder(nil).find_each do |record|
|
SeveredRelationship.where(local_account_id: other_account.id).reorder(nil).find_each do |record|
|
||||||
record.update_attribute(:remote_account_id, id)
|
record.update_attribute(:local_account_id, id)
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SeveredRelationship.where(remote_account_id: other_account.id).reorder(nil).find_each do |record|
|
||||||
|
record.update_attribute(:remote_account_id, id)
|
||||||
|
rescue ActiveRecord::RecordNotUnique
|
||||||
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -331,14 +331,14 @@ module Mastodon::CLI
|
||||||
end
|
end
|
||||||
|
|
||||||
def deduplicate_users_process_remember_token
|
def deduplicate_users_process_remember_token
|
||||||
if migrator_version < 2022_01_18_183010
|
return unless migrator_version < 2022_01_18_183010
|
||||||
duplicate_record_ids_without_nulls(:users, 'remember_token').each do |row|
|
|
||||||
users = User.where(id: row['ids'].split(',')).order(updated_at: :desc).to_a.drop(1)
|
|
||||||
say "Unsetting remember token for those accounts: #{users.map { |user| user.account.acct }.join(', ')}", :yellow
|
|
||||||
|
|
||||||
users.each do |user|
|
duplicate_record_ids_without_nulls(:users, 'remember_token').each do |row|
|
||||||
user.update!(remember_token: nil)
|
users = User.where(id: row['ids'].split(',')).order(updated_at: :desc).to_a.drop(1)
|
||||||
end
|
say "Unsetting remember token for those accounts: #{users.map { |user| user.account.acct }.join(', ')}", :yellow
|
||||||
|
|
||||||
|
users.each do |user|
|
||||||
|
user.update!(remember_token: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,23 +58,23 @@ module Mastodon::CLI
|
||||||
say("Visited #{processed} accounts and removed profile media totaling #{number_to_human_size(aggregate)}#{dry_run_mode_suffix}", :green, true)
|
say("Visited #{processed} accounts and removed profile media totaling #{number_to_human_size(aggregate)}#{dry_run_mode_suffix}", :green, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
unless options[:prune_profiles] || options[:remove_headers]
|
return if options[:prune_profiles] || options[:remove_headers]
|
||||||
processed, aggregate = parallelize_with_progress(MediaAttachment.cached.remote.where(created_at: ..time_ago)) do |media_attachment|
|
|
||||||
next if media_attachment.file.blank?
|
|
||||||
|
|
||||||
size = (media_attachment.file_file_size || 0) + (media_attachment.thumbnail_file_size || 0)
|
processed, aggregate = parallelize_with_progress(MediaAttachment.cached.remote.where(created_at: ..time_ago)) do |media_attachment|
|
||||||
|
next if media_attachment.file.blank?
|
||||||
|
|
||||||
unless dry_run?
|
size = (media_attachment.file_file_size || 0) + (media_attachment.thumbnail_file_size || 0)
|
||||||
media_attachment.file.destroy
|
|
||||||
media_attachment.thumbnail.destroy
|
|
||||||
media_attachment.save
|
|
||||||
end
|
|
||||||
|
|
||||||
size
|
unless dry_run?
|
||||||
|
media_attachment.file.destroy
|
||||||
|
media_attachment.thumbnail.destroy
|
||||||
|
media_attachment.save
|
||||||
end
|
end
|
||||||
|
|
||||||
say("Removed #{processed} media attachments (approx. #{number_to_human_size(aggregate)})#{dry_run_mode_suffix}", :green, true)
|
size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
say("Removed #{processed} media attachments (approx. #{number_to_human_size(aggregate)})#{dry_run_mode_suffix}", :green, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
option :start_after
|
option :start_after
|
||||||
|
|
|
@ -56,13 +56,11 @@ namespace :repo do
|
||||||
loop do
|
loop do
|
||||||
response = HTTP.headers('Authorization' => "token #{ENV['GITHUB_API_TOKEN']}").get("https://api.github.com/repos/#{REPOSITORY_NAME}/pulls/#{pull_request_number}")
|
response = HTTP.headers('Authorization' => "token #{ENV['GITHUB_API_TOKEN']}").get("https://api.github.com/repos/#{REPOSITORY_NAME}/pulls/#{pull_request_number}")
|
||||||
|
|
||||||
if response.code == 403
|
break unless response.code == 403
|
||||||
sleep_for = (response.headers['X-RateLimit-Reset'].to_i - Time.now.to_i).abs
|
|
||||||
puts "Sleeping for #{sleep_for} seconds to get over rate limit"
|
sleep_for = (response.headers['X-RateLimit-Reset'].to_i - Time.now.to_i).abs
|
||||||
sleep sleep_for
|
puts "Sleeping for #{sleep_for} seconds to get over rate limit"
|
||||||
else
|
sleep sleep_for
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
pull_request = Oj.load(response.to_s)
|
pull_request = Oj.load(response.to_s)
|
||||||
|
|
Loading…
Reference in a new issue