summaryrefslogtreecommitdiff
path: root/server.rb
diff options
context:
space:
mode:
authorpdp8 <pdp8@pdp8.info>2023-06-21 18:56:21 +0200
committerpdp8 <pdp8@pdp8.info>2023-06-21 18:56:21 +0200
commit457a0bfdc74ed90b77d09d285281abca8a1396de (patch)
tree7a2391e1bf174eba780e1e989739aa5fb14526d2 /server.rb
parenta501b19ae87592da8e55ec28525b487be1eba92f (diff)
reply form, server helpers moved to server.rb
Diffstat (limited to 'server.rb')
-rw-r--r--server.rb73
1 files changed, 73 insertions, 0 deletions
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