diff options
-rw-r--r-- | client.rb | 40 | ||||
-rw-r--r-- | generate-digest.rb | 3 | ||||
-rw-r--r-- | helpers.rb | 39 | ||||
-rw-r--r-- | server.rb | 45 |
4 files changed, 68 insertions, 59 deletions
@@ -122,7 +122,7 @@ post "/unfollow/*" do end post "/login" do - session["client"] = true if params["secret"] == File.read(".pwd").chomp + session["client"] = true if OpenSSL::Digest::SHA256.base64digest(params["secret"]) == File.read(".digest").chomp redirect to("/") end @@ -168,7 +168,7 @@ helpers do :follow => follow, :content => item['content'], :attachment => item['attachment'], - :indent => 2, + :indent => 0, :replies => [] } end.compact @@ -183,7 +183,7 @@ helpers do @threads << i else @items.select{|it| it[:id] == i[:parent] }.each do |it| - i[:indent] = it[:indent] + 2 + i[:indent] = it[:indent] + 4 it[:replies] << i end end @@ -195,38 +195,4 @@ helpers do erb :item end - def people - File.read('cache/people.tsv').split("\n").collect {|l| l.chomp.split("\t")} - end - - def mention actor - person = people.select{|p| p[1] == actor} - if person.empty? - a = fetch(actor) - return nil unless a - mention = "#{a["preferredUsername"]}@#{URI(actor).host}" - File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} - mention - else - person[0][0] - end - end - - def actor mention - mention = mention.sub(/^@/, '').chomp - actors = people.select{|p| p[0] == mention} - if actors.empty? - user, server = mention.split("@") - a = fetch("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", "application/jrd+json") - return nil unless a - actor = a["links"].select { |l| - l["rel"] == "self" - }[0]["href"] - File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} - actor - else - actors[0][1] - end - end - end diff --git a/generate-digest.rb b/generate-digest.rb new file mode 100644 index 0000000..616ac81 --- /dev/null +++ b/generate-digest.rb @@ -0,0 +1,3 @@ +require "openssl" + +puts OpenSSL::Digest::SHA256.base64digest(ARGV.first.chomp) @@ -1,7 +1,8 @@ helpers do def curl ext, url - response = `/run/current-system/sw/bin/curl -ifsSL #{ext} #{url}` + #p "/run/current-system/sw/bin/curl -fsSL #{ext} #{url}" + response = `/run/current-system/sw/bin/curl -fsSL #{ext} #{url}` $?.success? ? response : nil end @@ -27,9 +28,43 @@ helpers do 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 + '"' - curl "-X POST -H 'Content-Type: application/activity+json' -H 'Host: #{host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}'", inbox + p curl("-X POST -H 'Content-Type: application/activity+json' -H 'Host: #{host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}'", inbox) $?.success? end + def people + File.read('cache/people.tsv').split("\n").collect {|l| l.chomp.split("\t")} + end + + def mention actor + person = people.select{|p| p[1] == actor} + if person.empty? + a = fetch(actor) + return nil unless a + mention = "#{a["preferredUsername"]}@#{URI(actor).host}" + File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} + mention + else + person[0][0] + end + end + + def actor mention + mention = mention.sub(/^@/, '').chomp + actors = people.select{|p| p[0] == mention} + if actors.empty? + user, server = mention.split("@") + a = fetch("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", "application/jrd+json") + return nil unless a + actor = a["links"].select { |l| + l["rel"] == "self" + }[0]["href"] + File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"} + actor + else + actors[0][1] + end + end + end @@ -1,33 +1,33 @@ # server-server post "/inbox" do - verify! request.body.rewind # in case someone already read it - body = request.body.read - action = JSON.parse body + @body = request.body.read + @action = JSON.parse @body + verify! - case action["type"] + case @action["type"] when "Create" - create action["object"] + create @action["object"] when "Delete" - delete action["object"] + delete @action["object"] when "Update" - delete action["object"] - create action["object"] + delete @action["object"] + create @action["object"] when "Follow" - File.open(File.join("public", "followers", mention(action["actor"]) + ".json"), "w+") { |f| f.puts body } + File.open(File.join("public", "followers", mention(@action["actor"]) + ".json"), "w+") { |f| f.puts @body } accept = { "@context" => "https://www.w3.org/ns/activitystreams", "id" => File.join(SOCIAL_URL + "#accepts", SecureRandom.uuid), "type" => "Accept", "actor" => ACTOR, - "object" => action } - send_signed accept, action["actor"] + "object" => @action } + send_signed accept, @action["actor"] when "Undo" - o = action["object"] + o = @action["object"] case o["type"] when "Follow" Dir["public/followers/*.json"].each do |follower| @@ -36,14 +36,14 @@ post "/inbox" do end when "Accept" - o = action["object"] + 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" - download action["object"] + download @action["object"] #when "Move" #when "Add" #when "Remove" @@ -51,8 +51,8 @@ post "/inbox" do #when "Block" else - p "Unknown action: #{action['type']}" - p body + p "Unknown @action: #{@action['type']}" + p @body end end @@ -81,10 +81,8 @@ helpers do def verify! # verify digest - request.body.rewind # in case someone already read it - body = request.body.read sha256 = OpenSSL::Digest::SHA256.new - digest = "SHA-256=" + sha256.base64digest(body) + digest = "SHA-256=" + sha256.base64digest(@body) halt 403 unless digest == request.env["HTTP_DIGEST"] signature_params = {} @@ -97,6 +95,12 @@ helpers do headers = signature_params['headers'] signature = Base64.decode64(signature_params['signature']) + if @action["type"] == "Delete" # deleted users do not return actors + delete @action["object"] + halt 200 + end + + jj @action actor = fetch key_id halt 403 unless actor key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) @@ -129,7 +133,8 @@ helpers do end def download object_url - create fetch(object_url) + object = fetch(object_url) + object and object["type"] ? create(object) : p(object_url, object) end def delete object |