From 79e3bf726b7166c5ec641ea02b75f82a74f31698 Mon Sep 17 00:00:00 2001 From: pdp8 Date: Sun, 23 Apr 2023 19:26:00 +0200 Subject: inbox/outbox GET --- application.rb | 184 ++++++++++++++++++++++----------------------------------- 1 file changed, 72 insertions(+), 112 deletions(-) (limited to 'application.rb') diff --git a/application.rb b/application.rb index 7618855..6e700fd 100644 --- a/application.rb +++ b/application.rb @@ -14,6 +14,9 @@ ACTOR = URI.join(SOCIAL_URL, USER) MATRIX = "@#{USER}:matrix.#{WWW_DOMAIN}" +OUTBOX = File.join(File.dirname(__FILE__), "outbox") +INBOX = File.join(File.dirname(__FILE__), "inbox") + class Application def call(env) code = 404 @@ -24,41 +27,21 @@ class Application when 'POST' case env["REQUEST_URI"] - when "/inbox" - type = "text/plain" - signature_header = {} - if env["HTTP_SIGNATURE"].split(',') - env["HTTP_SIGNATURE"].split(',').each do |pair| - k, v = pair.split('=') - signature_header[k] = v.gsub('"', '') - end - key_id = signature_header['keyId'] - headers = signature_header['headers'] - signature = Base64.urlsafe_decode64(signature_header['signature'].encode("ascii-8bit")) - uri = URI(key_id) - res = Net::HTTP.get_response(uri) - actor = JSON.parse(res.body) - key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) - - comparison_string = headers.split(' ').map do |signed_header_name| - if signed_header_name == '(request-target)' - '(request-target): post /inbox' - else - "#{signed_header_name}: #{env["HTTP_" + signed_header_name.upcase]}" - end - end.join("\n") - if key.verify(OpenSSL::Digest::SHA256.new, signature, comparison_string.encode("ascii-8bit")) - input = JSON.parse(env["rack.input"].gets) - # p input - code = 200 - response = "OK" - else - code = 401 - response = 'Request signature could not be verified' - end + when "/inbox" # receive from server + if verify(env) + input = JSON.parse(env["rack.input"].gets) + # p input["type"] + code = 200 + response = "OK" else code = 401 - response = 'Request signature could not be verified' + response = "not verified" + end + + when "/outbox" + input = JSON.parse(env["rack.input"].gets) + case input["type"] + when "Create" end end @@ -68,95 +51,72 @@ class Application case env["REQUEST_URI"] when "/.well-known/webfinger?resource=acct:#{ACCOUNT}" - code = 200 type = "application/jrd+json" - response = { - "subject" => "acct:#{ACCOUNT}", - "links" => [ - { - "rel" => "self", - "type" => "application/activity+json", - "href" => ACTOR - } - ] - } + response = File.read("webfinger") + code = 200 when "/#{USER}" + response = File.read("pdp8") code = 200 - response = { - "@context" => ["https://www.w3.org/ns/activitystreams"], - "id" => ACTOR, - "type" => "Person", - "preferredUsername" => USER, - "name" => USER, - "inbox" => URI.join(SOCIAL_URL, "inbox"), - "outbox" => URI.join(SOCIAL_URL, "outbox"), - "following" => URI.join(SOCIAL_URL, "following"), - "followers" => URI.join(SOCIAL_URL, "followers"), - "liked" => URI.join(SOCIAL_URL, "liked"), - "icon" => { - "type" => "Image", - "url" => "https://pdp8.info/pdp8.png" - }, - "attachment": [ - { - "type": "PropertyValue", - "name": "Web", - "value": "#{WWW_DOMAIN}" - }, - { - "type": "PropertyValue", - "name": "Fediverse", - "value": "@#{ACCOUNT}" - }, - { - "type": "PropertyValue", - "name": "Matrix", - "value": "#{MATRIX}" - } - ], - "publicKey" => { - "@context" => "https://w3id.org/security/v1", - "@type" => "Key", - "id" => "#{ACTOR}#main-key", - "owner" => ACTOR, - "publicKeyPem" => File.read("public.pem") - } - } when "/outbox" + response = ordered_collection OUTBOX code = 200 + + when "/inbox" type = "application/activity+json" - response = { - "@context" => "https://www.w3.org/ns/activitystreams", - "summary" => "", - "type" => "OrderedCollection", - "totalItems" => 2, - # TODO generate items from src/www - "orderedItems" => [ - { - "type" => "Note", - "name" => "A Simple Note", - "tag" => [ - { - "type" => "Hashtag", - "name" => "#activitypub", - "href" => "https://s3lph.me/activitypub/tags/activitypub" - }, - ] - }, - { - "type" => "Note", - "name" => "Another Simple Note" - } - ] - } - when "/following" - when "/followers" - when "/liked" + response = ordered_collection INBOX + code = 200 + + # when "/following" + # when "/followers" + # when "/liked" end end - [code, { "Content-Type" => type }, [response.to_json]] + [code, { "Content-Type" => type }, [response]] + end + + def ordered_collection dir + posts = Dir[File.join(dir, "*.json")].sort.reverse.collect { |f| p f; JSON.parse(File.read f) } + { + "@context" => "https://www.w3.org/ns/activitystreams", + "summary" => "pdp8 outbox", + "type" => "OrderedCollection", + "totalItems" => posts.size, + "orderedItems" => posts, + }.to_json + end + + def verify(env) + begin + signature_header = {} + env["HTTP_SIGNATURE"].split(',').each do |pair| + k, v = pair.split('=') + signature_header[k] = v.gsub('"', '') + end + key_id = signature_header['keyId'] + headers = signature_header['headers'] + signature = Base64.urlsafe_decode64(signature_header['signature'].encode("ascii-8bit")) + uri = URI(key_id) + res = Net::HTTP.get_response(uri) + actor = JSON.parse(res.body) + key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) + + comparison_string = headers.split(' ').map do |signed_header_name| + if signed_header_name == '(request-target)' + '(request-target): post /inbox' + else + "#{signed_header_name}: #{env["HTTP_" + signed_header_name.upcase]}" + end + end.join("\n") + if key.verify(OpenSSL::Digest::SHA256.new, signature, comparison_string.encode("ascii-8bit")) + true + else + false + end + rescue + false + end end end -- cgit v1.2.3