From 0751c83a552e3b5d7b4270823c1d231b2976df8f Mon Sep 17 00:00:00 2001 From: pdp8 Date: Thu, 8 Jun 2023 18:00:57 +0200 Subject: POST with curl instead of Net::HTTP because of ruby openssl eof errors --- activitypub.rb | 90 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/activitypub.rb b/activitypub.rb index a67c9ba..6e82bc4 100644 --- a/activitypub.rb +++ b/activitypub.rb @@ -38,7 +38,6 @@ end post "/inbox" do # server-server request.body.rewind # in case someone already read it body = request.body.read - #p body action = JSON.parse body case action["type"] @@ -173,20 +172,23 @@ end get "/", :provides => 'html' do protected! - @inbox = Dir['./inbox/*'].sort.collect do |file| + @inbox = Dir['./inbox/*.json'].sort.collect do |file| item = JSON.parse(File.read(file)) - mention = mention(item['attributedTo']) - following_path = File.join('public', 'following', mention + '.json') - File.exists?(following_path) ? follow = 'unfollow' : follow = 'follow' - { :file => file, - :actor_url => item['attributedTo'], - :mention => mention, - :follow => follow, - :content => item['content'], - :attachment => item['attachment'] - } - end - p @inbox + unless item['type'] == 'Person' + mention = mention(item['attributedTo']) + #p mention + following_path = File.join('public', 'following', mention + '.json') + File.exists?(following_path) ? follow = 'unfollow' : follow = 'follow' + { :file => file, + :actor_url => item['attributedTo'], + :mention => mention, + :follow => follow, + :content => item['content'], + :attachment => item['attachment'] + } + end + end.compact + #p @inbox erb :index end @@ -214,17 +216,44 @@ def create object end def mention actor - "#{get(actor)["preferredUsername"]}@#{URI(actor).host}" + people = File.read('inbox/people.tsv').split("\n").collect {|l| l.chomp.split("\t")} + person = people.select{|p| p[1] == actor} + #p person + if person.empty? + #p actor + mention = "#{fetch(actor)["preferredUsername"]}@#{URI(actor).host}" + File.open('inbox/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} + mention + else + person[0][0] + end +end + +def actor mention + mention = mention.sub(/^@/, '').chomp + user, server = mention.split("@") + fetch("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", + "application/jrd+json")["links"].select { |l| + l["rel"] == "self" + }[0]["href"] end -def get url, accept = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' +def fetch url, accept = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', limit = 10 + p url uri = URI(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true header = { 'Accept' => accept } request = Net::HTTP::Get.new(uri.request_uri, header) response = http.request(request) - JSON.parse(response.body) + case response + when Net::HTTPSuccess + return JSON.parse(response.body) + when Net::HTTPRedirection + fetch response['location'], accept, limit-1 + else + puts "Unknown response: #{response.code}, #{response.message}\n#{response.code}" + end end def ordered_collection dir @@ -252,7 +281,8 @@ def send_signed object, url signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string)) signed_header = 'keyId="' + ACTOR + '#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="' + signature + '"' - uri = URI.parse(get(url)["inbox"]) +=begin + uri = URI.parse(fetch(url)["inbox"]) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true header = { @@ -267,16 +297,19 @@ def send_signed object, url p uri, body http.request(request) + puts "/run/current-system/sw/bin/curl -X POST -H 'Content-Type: application/activity+json' -H 'Host: #{uri.host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}' #{url}" +=end + `/run/current-system/sw/bin/curl -X POST -H 'Content-Type: application/activity+json' -H 'Host: #{uri.host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}' #{url}` end def inbox uri - URI(get(uri)["inbox"]).request_uri + URI(fetch(uri)["inbox"]).request_uri end def verify_signature env # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb # TODO verify digest - begin + #begin signature_params = {} env["HTTP_SIGNATURE"].split(',').each do |pair| k, v = pair.split('=') @@ -287,7 +320,7 @@ def verify_signature env headers = signature_params['headers'] signature = Base64.decode64(signature_params['signature']) - actor = get key_id + actor = fetch key_id key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) comparison = headers.split(' ').map do |signed_params_name| @@ -301,16 +334,7 @@ def verify_signature env end.join("\n") key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison) - rescue - false - end -end - -def actor mention - mention = mention.sub(/^@/, '').chomp - user, server = mention.split("@") - get("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", - "application/jrd+json")["links"].select { |l| - l["rel"] == "self" - }[0]["href"] + #rescue + #false + #end end -- cgit v1.2.3