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.

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