josephholsten/discodactyl

View on GitHub
bin/webfinger

Summary

Maintainability
Test Coverage
#!/usr/bin/env ruby
libdir = File.expand_path('../../lib', __FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

require 'discodactyl'
require 'discodactyl/cli'
require 'open-uri'
require 'action_view'
require 'prism'
require 'feedzirra'
require 'logger'

log = Logger.new(STDERR)
Discodactyl.log = log

if ARGV.length == 0
    puts "Usage: #{__FILE__} user@host"
    exit 0
end

if ARGV[0].match /^-d/
  log.level = Logger::DEBUG
  # ARGV.unshift
  ARGV.shift
else
  log.level = Logger::WARN
end

# parse identifier
raw_acct = ARGV[0]
acct = URI::ACCT.parse(raw_acct)

# Perform LRDD discovery on acct with the webfinger relation
finger_rel = "lrdd"
begin
  webfinger_uris = Discodactyl::ResourceDiscovery.get_uris_by_rel(acct, finger_rel, 'uri' => acct)
rescue Discodactyl::HostMetaHTTPError => error
  if error.io.status[1] == 'Not Found'
    abort "No host meta webfinger information found at #{error.io.base_uri}. Is the file there?"
  else
    raise
  end
rescue Discodactyl::HostMetaSocketError => error
  abort "Could not connect to #{error.host}:#{error.port}. Is your internet connection working?"
end

abort "URI didn't have any linked webfinger URIs" if webfinger_uris.empty?

# retrieve user disco doc
begin
  disco_uri = webfinger_uris.first
  disco_res = open(disco_uri)
rescue OpenURI::HTTPError
  abort "Couldn't open the disco doc at #{disco_uri}. Is your host-meta pointed at the right place?"
end

# parse disco doc
begin
  disco = Discodactyl::JRD::Document.parse(disco_res)
  log.debug "disco doc <#{webfinger_uris.first}>:\n#{disco.inspect}\n"
rescue Discodactyl::JRD::ParseError => e
  log.debug "disco doc doesn't seem to be a JRD #{e.message}"
  disco_res.rewind
  disco = Discodactyl::XRD::Document.parse(disco_res)
  log.debug "disco doc <#{webfinger_uris.first}>:\n#{disco}\n"
end

log.debug "links: #{disco.links.map{|r| [r.rel, r.type, r.href]}.inspect}"
log.debug "rels: #{disco.rels.inspect}"

if disco.subject
  log.debug "subject: #{disco.subject}"
  unless acct.to_s == disco.subject.to_s
    abort "Disco doc's subject <#{disco.subject}> doesn't match account we're webfingering <#{acct}>"
  end
else
  log.warn("Disco doc didn't list a subject. Assuming everything is well.")
end

links_with_titles = disco.links.select{|l| l.title.present? }
links_with_titles.each do |link|
  puts "#{link.title}: #{link.to_uri}"
end

Discodactyl::KNOWN_RELS.each do |rel, name|
  uri = disco.uris_by_rel(rel).first
  formatter = Discodactyl::CLI::Format.for_rel(rel)
  formatter.call(uri, STDOUT)
end