summaryrefslogtreecommitdiff
path: root/server.rb
diff options
context:
space:
mode:
Diffstat (limited to 'server.rb')
-rw-r--r--server.rb169
1 files changed, 87 insertions, 82 deletions
diff --git a/server.rb b/server.rb
index 2c24bb9..809538b 100644
--- a/server.rb
+++ b/server.rb
@@ -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}",