diff options
Diffstat (limited to 'server.rb')
-rw-r--r-- | server.rb | 169 |
1 files changed, 87 insertions, 82 deletions
@@ -1,59 +1,22 @@ -# server-server -post "/inbox" do +before '/inbox' do request.body.rewind # in case someone already read it @body = request.body.read - @action = JSON.parse @body - verify! - - case @action["type"] - - when "Create" - create @action["object"] - - when "Delete" - delete @action["object"] - - when "Update" - delete @action["object"] - create @action["object"] - - when "Follow" - 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"] - - when "Undo" - o = @action["object"] - case o["type"] - when "Follow" - Dir["public/followers/*.json"].each do |follower| - FileUtils.rm follower if JSON.parse(File.read(follower))["actor"] == o["actor"] - 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 + @activity = JSON.parse @body + @object = @activity['object'] + @object = fetch(@object) if @object.is_a? String and @object.match(/^http/) +end - when "Announce" - download @action["object"] - #when "Move" - #when "Add" - #when "Remove" - #when "Like" - #when "Block" +# client-server +post '/outbox' do + protected! + #send_signed @activity +end - else - p "Unknown @action: #{@action['type']}" - p @body - end +# server-server +post "/inbox" do + verify! + type = @activity['type'].downcase.to_sym + respond_to?(type) ? send(type) : p("Unknown activity: #{type}") end # public @@ -61,20 +24,16 @@ get "/.well-known/webfinger" do request["resource"] == "acct:#{ACCOUNT}" ? send_file("./public/webfinger", :type => "application/jrd+json") : halt(404) end -get "/pdp8", :provides => 'html' do - redirect 'https://pdp8.info' -end - -get "/pdp8" do - send_file "pdp8.json", :type => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' -end - ["/outbox","/following","/followers"].each do |path| get path do - ordered_collection(path).to_json + ordered_collection(File.join(PUBLIC_DIR,path)).to_json end end +get '/tags/:tag' do |tag| + ordered_collection(File.join(TAGS,tag)).to_json +end + helpers do # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb @@ -95,13 +54,11 @@ 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"] + actor = fetch key_id + if not actor and @activity["type"] == "Delete" # deleted users do not return actors halt 200 end - jj @action - actor = fetch key_id halt 403 unless actor key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem']) @@ -118,33 +75,81 @@ helpers do halt 403 unless key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison) 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 + def create + unless object_exists? + File.open(object_file, "w+") { |f| f.puts @object.to_json } + if @object and @object['inReplyTo'] + @object = fetch @object['inReplyTo'] + create if @object end end end - def download object_url - object = fetch(object_url) - object and object["type"] ? create(object) : p(object_url, object) + def delete + Dir["inbox/*/*.json"].each do |file| + FileUtils.rm file if JSON.parse(File.read(file))['id'] == @object['id'] + end + end + + def update + delete + create + end + + def announce + create end - def delete object - Dir["inbox/*.json"].each do |doc| - FileUtils.rm doc if JSON.parse(File.read(doc))["id"] == object["id"] + def accept + if @object['type'] == 'Follow' + File.open(File.join(FOLLOWING, mention(@object['object'])+'.json'),'w+'){|f| f.puts @object.to_json} end end + def undo + if @object['type'] == 'Follow' + Dir[File.join(FOLLOWERS, '*.json')].each do |follower| + FileUtils.rm follower if JSON.parse(File.read(follower))["actor"] == @object["actor"] + end + end + end + + def follow + File.open(File.join(FOLLOWERS, mention(@activity['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' => @activity, + 'to' => [ @activity['actor'] ] + } + send_signed accept#, @activity['actor'] + end + + #when "Move" + #when "Add" + #when "Remove" + #when "Like" + #when "Block" + + def inbox + Dir[File.join(INBOX,'*','*.json')].collect do |file| + JSON.parse(File.read(file)) + end.sort_by { |o| o["published"] } + end + + def object_exists? + not inbox.select{|o| o['id'] == @object['id']}.empty? + end + + def object_file + dir = File.join 'inbox', @object['type'].downcase + FileUtils.mkdir_p dir + File.join dir, "#{Time.now.strftime('%Y-%m-%dT%H:%M:%S.%N')}.json" + end + def ordered_collection dir - posts = Dir[File.join("public",dir, "*.json")].collect { |f| JSON.parse(File.read f) }.sort_by { |o| o["published"] } + posts = Dir[File.join(dir, "*.json")].collect { |f| JSON.parse(File.read f) }.sort_by { |o| o["published"] } { "@context" => "https://www.w3.org/ns/activitystreams", "summary" => "#{USER} #{dir}", |