闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.0 KiB

  1. # frozen_string_literal: true
  2. class Keys::QueryService < BaseService
  3. include JsonLdHelper
  4. class Result < ActiveModelSerializers::Model
  5. attributes :account, :devices
  6. def initialize(account, devices)
  7. super(
  8. account: account,
  9. devices: devices || [],
  10. )
  11. end
  12. def find(device_id)
  13. @devices.find { |device| device.device_id == device_id }
  14. end
  15. end
  16. class Device < ActiveModelSerializers::Model
  17. attributes :device_id, :name, :identity_key, :fingerprint_key
  18. def initialize(attributes = {})
  19. super(
  20. device_id: attributes[:device_id],
  21. name: attributes[:name],
  22. identity_key: attributes[:identity_key],
  23. fingerprint_key: attributes[:fingerprint_key],
  24. )
  25. @claim_url = attributes[:claim_url]
  26. end
  27. def valid_claim_url?
  28. return false if @claim_url.blank?
  29. begin
  30. parsed_url = Addressable::URI.parse(@claim_url).normalize
  31. rescue Addressable::URI::InvalidURIError
  32. return false
  33. end
  34. %w(http https).include?(parsed_url.scheme) && parsed_url.host.present?
  35. end
  36. end
  37. def call(account)
  38. @account = account
  39. if @account.local?
  40. query_local_devices!
  41. else
  42. query_remote_devices!
  43. end
  44. Result.new(@account, @devices)
  45. end
  46. private
  47. def query_local_devices!
  48. @devices = @account.devices.map { |device| Device.new(device) }
  49. end
  50. def query_remote_devices!
  51. return if @account.devices_url.blank?
  52. json = fetch_resource(@account.devices_url)
  53. return if json['items'].blank?
  54. @devices = json['items'].map do |device|
  55. Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim'])
  56. end
  57. rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e
  58. Rails.logger.debug "Querying devices for #{@account.acct} failed: #{e}"
  59. nil
  60. end
  61. end