forked from asonix/mastodon
An uncommon but somewhat difficult to digagnose issue is dealing with improperly-seeded databases. In such cases, instance-signed fetches will fail with a ActiveRecord::RecordNotFound error, usually caught and handled as generic 404, leading people to think the remote resource itself has not been found, while it's the local instance actor that does not exist. This commit changes the code so that failure to find the instance actor automatically creates a new one, so that improperly-seeded databases do not cause any issue.
64 lines
1.5 KiB
Ruby
64 lines
1.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module AccountFinderConcern
|
|
extend ActiveSupport::Concern
|
|
|
|
class_methods do
|
|
def find_local!(username)
|
|
find_local(username) || raise(ActiveRecord::RecordNotFound)
|
|
end
|
|
|
|
def find_remote!(username, domain)
|
|
find_remote(username, domain) || raise(ActiveRecord::RecordNotFound)
|
|
end
|
|
|
|
def representative
|
|
Account.find(-99)
|
|
rescue ActiveRecord::RecordNotFound
|
|
Account.create!(id: -99, actor_type: 'Application', locked: true, username: Rails.configuration.x.local_domain)
|
|
end
|
|
|
|
def find_local(username)
|
|
find_remote(username, nil)
|
|
end
|
|
|
|
def find_remote(username, domain)
|
|
AccountFinder.new(username, domain).account
|
|
end
|
|
end
|
|
|
|
class AccountFinder
|
|
attr_reader :username, :domain
|
|
|
|
def initialize(username, domain)
|
|
@username = username
|
|
@domain = domain
|
|
end
|
|
|
|
def account
|
|
scoped_accounts.order(id: :asc).take
|
|
end
|
|
|
|
private
|
|
|
|
def scoped_accounts
|
|
Account.unscoped.tap do |scope|
|
|
scope.merge! with_usernames
|
|
scope.merge! matching_username
|
|
scope.merge! matching_domain
|
|
end
|
|
end
|
|
|
|
def with_usernames
|
|
Account.where.not(Account.arel_table[:username].lower.eq '')
|
|
end
|
|
|
|
def matching_username
|
|
Account.where(Account.arel_table[:username].lower.eq username.to_s.downcase)
|
|
end
|
|
|
|
def matching_domain
|
|
Account.where(Account.arel_table[:domain].lower.eq(domain.nil? ? nil : domain.to_s.downcase))
|
|
end
|
|
end
|
|
end
|