summary refs log tree commit diff
diff options
context:
space:
mode:
authorpdp8 <pdp8@pdp8.info>2023-06-09 20:59:20 +0200
committerpdp8 <pdp8@pdp8.info>2023-06-09 20:59:20 +0200
commit0c3a5b8565fb7148714696eedd3d5adf4fc68641 (patch)
tree1bbac0a9427da5b4ba0ee252abd234bd9b15919f
parentf65f10f8c0c45b53013154da22217f8ec1646611 (diff)
wait for following accept, verify! helper
-rw-r--r--activitypub.rb91
1 files changed, 38 insertions, 53 deletions
diff --git a/activitypub.rb b/activitypub.rb
index ba763e3..9a57008 100644
--- a/activitypub.rb
+++ b/activitypub.rb
@@ -61,6 +61,14 @@ post "/inbox" do # server-server
       end
     end
 
+  when "Accept"
+    o = action["object"]
+    case o["type"]
+    when "Follow"
+      File.open(File.join("public","following",mention(o['object'])+".json"),"w+"){|f| f.puts o.to_json}
+    end
+  #when "Announce"
+
   else
     p "Unknown action: #{action['type']}"
     p body
@@ -133,14 +141,12 @@ post "/follow/*" do
   protected!
   mention = params['splat'][0]
   actor = actor(mention)
-  following_path = File.join("public", "following", mention + ".json")
   follow = { "@context" => "https://www.w3.org/ns/activitystreams",
-             "id" => File.join(SOCIAL_URL, following_path),
+             "id" => File.join(SOCIAL_URL, "following", mention + ".json"),
              "type" => "Follow",
              "actor" => ACTOR,
              "object" => actor }
   send_signed follow, actor
-  File.open(following_path, "w+") { |f| f.puts follow.to_json }
   redirect to("/")
 end
 
@@ -199,30 +205,36 @@ helpers do
   def verify!
     # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb
     # TODO verify digest
-    signature_params = {}
-    request.env["HTTP_SIGNATURE"].split(',').each do |pair|
-      k, v = pair.split('=')
-      signature_params[k] = v.gsub('"', '')
-    end
-
-    key_id = signature_params['keyId']
-    headers = signature_params['headers']
-    signature = Base64.decode64(signature_params['signature'])
-
-    actor = fetch key_id
-    key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem'])
-
-    comparison = headers.split(' ').map do |signed_params_name|
-      if signed_params_name == '(request-target)'
-        '(request-target): post /inbox'
-      elsif signed_params_name == 'content-type'
-        "#{signed_params_name}: #{request.env["CONTENT_TYPE"]}"
-      else
-        "#{signed_params_name}: #{request.env["HTTP_" + signed_params_name.upcase]}"
+    begin
+      signature_params = {}
+      request.env["HTTP_SIGNATURE"].split(',').each do |pair|
+        k, v = pair.split('=')
+        signature_params[k] = v.gsub('"', '')
       end
-    end.join("\n")
 
-    halt 400 unless key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison)
+      key_id = signature_params['keyId']
+      headers = signature_params['headers']
+      signature = Base64.decode64(signature_params['signature'])
+
+      actor = fetch key_id
+      key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem'])
+
+      comparison = headers.split(' ').map do |signed_params_name|
+        if signed_params_name == '(request-target)'
+          '(request-target): post /inbox'
+        elsif signed_params_name == 'content-type'
+          "#{signed_params_name}: #{request.env["CONTENT_TYPE"]}"
+        else
+          "#{signed_params_name}: #{request.env["HTTP_" + signed_params_name.upcase]}"
+        end
+      end.join("\n")
+
+      halt 400 unless key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison)
+    rescue => e
+      p request.env["HTTP_SIGNATURE"]
+      p e
+      halt 400
+    end
   end
 end
 
@@ -337,9 +349,7 @@ end
 def mention actor
   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
@@ -358,7 +368,6 @@ def actor mention
 end
 
 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
@@ -400,33 +409,9 @@ 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 + '"'
 
-=begin
-  uri = URI.parse(fetch(url)["inbox"])
-  http = Net::HTTP.new(uri.host, uri.port)
-  http.use_ssl = true
-  header = {
-    'Content-Type' => 'application/activity+json',
-    'Host' => uri.host,
-    'Date' => date,
-    'Digest' => digest,
-    'Signature' => signed_header,
-  }
-  request = Net::HTTP::Post.new(uri.request_uri, header)
-  request.body = body
-
-  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}`
+  puts `/run/current-system/sw/bin/curl -i -X POST -H 'Content-Type: application/activity+json' -H 'Host: #{uri.host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}' #{fetch(url)['inbox']}`
 end
 
 def inbox uri
   URI(fetch(uri)["inbox"]).request_uri
 end
-
-def verify_signature env
-  #rescue
-    #false
-  #end
-end