From 457a0bfdc74ed90b77d09d285281abca8a1396de Mon Sep 17 00:00:00 2001 From: pdp8 Date: Wed, 21 Jun 2023 18:56:21 +0200 Subject: reply form, server helpers moved to server.rb --- server.rb | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'server.rb') diff --git a/server.rb b/server.rb index 13153b8..b5076f3 100644 --- a/server.rb +++ b/server.rb @@ -74,3 +74,76 @@ end ordered_collection(path).to_json end end + +helpers do + + # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb + def verify! + # TODO verify digest + begin + 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]}" + end + end.join("\n") + + halt 400 unless key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison) + rescue => e + p request.env["HTTP_SIGNATURE"], e + halt 400 + end + end + + def create object + unless object['type'] == 'Person' + doc = File.join("inbox", "#{Time.now.strftime('%Y-%m-%dT%H:%M:%S.%N')}.json") + File.open(doc, "w+") { |f| f.puts object.to_json } + if object['inReplyTo'] + @dir = 'inbox' + items + if @items.select{|it| it[:id] == object['inReplyTo'] }.empty? + download object['inReplyTo'] + end + end + end + end + + def download object_url + create fetch(object_url) + end + + def delete object + Dir["inbox/*.json"].each do |doc| + FileUtils.rm doc if JSON.parse(File.read(doc))["id"] == object["id"] + end + end + + def ordered_collection dir + posts = Dir[File.join("public",dir, "*.json")].collect { |f| JSON.parse(File.read f) }.sort_by { |o| o["published"] } + { + "@context" => "https://www.w3.org/ns/activitystreams", + "summary" => "#{USER} #{dir}", + "type" => "OrderedCollection", + "totalItems" => posts.size, + "orderedItems" => posts, + } + end + +end -- cgit v1.2.3