80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
class Keys::QueryService < BaseService
 | 
						|
  include JsonLdHelper
 | 
						|
 | 
						|
  class Result < ActiveModelSerializers::Model
 | 
						|
    attributes :account, :devices
 | 
						|
 | 
						|
    def initialize(account, devices)
 | 
						|
      super(
 | 
						|
        account: account,
 | 
						|
        devices: devices || [],
 | 
						|
      )
 | 
						|
    end
 | 
						|
 | 
						|
    def find(device_id)
 | 
						|
      @devices.find { |device| device.device_id == device_id }
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  class Device < ActiveModelSerializers::Model
 | 
						|
    attributes :device_id, :name, :identity_key, :fingerprint_key
 | 
						|
 | 
						|
    def initialize(attributes = {})
 | 
						|
      super(
 | 
						|
        device_id: attributes[:device_id],
 | 
						|
        name: attributes[:name],
 | 
						|
        identity_key: attributes[:identity_key],
 | 
						|
        fingerprint_key: attributes[:fingerprint_key],
 | 
						|
      )
 | 
						|
      @claim_url = attributes[:claim_url]
 | 
						|
    end
 | 
						|
 | 
						|
    def valid_claim_url?
 | 
						|
      return false if @claim_url.blank?
 | 
						|
 | 
						|
      begin
 | 
						|
        parsed_url = Addressable::URI.parse(@claim_url).normalize
 | 
						|
      rescue Addressable::URI::InvalidURIError
 | 
						|
        return false
 | 
						|
      end
 | 
						|
 | 
						|
      %w(http https).include?(parsed_url.scheme) && parsed_url.host.present?
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def call(account)
 | 
						|
    @account = account
 | 
						|
 | 
						|
    if @account.local?
 | 
						|
      query_local_devices!
 | 
						|
    else
 | 
						|
      query_remote_devices!
 | 
						|
    end
 | 
						|
 | 
						|
    Result.new(@account, @devices)
 | 
						|
  end
 | 
						|
 | 
						|
  private
 | 
						|
 | 
						|
  def query_local_devices!
 | 
						|
    @devices = @account.devices.map { |device| Device.new(device) }
 | 
						|
  end
 | 
						|
 | 
						|
  def query_remote_devices!
 | 
						|
    return if @account.devices_url.blank?
 | 
						|
 | 
						|
    json = fetch_resource(@account.devices_url)
 | 
						|
 | 
						|
    return if json['items'].blank?
 | 
						|
 | 
						|
    @devices = json['items'].map do |device|
 | 
						|
      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'])
 | 
						|
    end
 | 
						|
  rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e
 | 
						|
    Rails.logger.debug { "Querying devices for #{@account.acct} failed: #{e}" }
 | 
						|
    nil
 | 
						|
  end
 | 
						|
end
 |