bin/webfinger
#!/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