From d2c4d3b49e6b790d14f6dcb94c2ae0641559d2cf Mon Sep 17 00:00:00 2001 From: pdp8 Date: Fri, 19 May 2023 22:50:54 +0200 Subject: follow and followers --- application.rb | 133 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 93 insertions(+), 40 deletions(-) (limited to 'application.rb') diff --git a/application.rb b/application.rb index 9e4e3a8..66b47b2 100644 --- a/application.rb +++ b/application.rb @@ -47,9 +47,27 @@ class Application puts input when "Follow" File.open(File.join("followers", SecureRandom.uuid + ".json"), "w+") { |f| f.puts input } - # TODO return accept activity + accept = { "@context" => "https://www.w3.org/ns/activitystreams", + "id" => File.join(SOCIAL_URL + "#accepts", SecureRandom.uuid), + "type" => "Accept", + "actor" => ACTOR, + "object" => JSON.parse(input) } + send accept, [accept["object"]["actor"]] when "Undo" - puts input + o = object["object"] + # puts o + case o["type"] + when "Follow" + Dir["followers/*.json"].each do |follower| + puts follower + # puts JSON.parse(File.read(follower))["actor"] + if JSON.parse(File.read(follower))["actor"] == o["actor"] + FileUtils.rm follower + end + end + # ordered_collection("followers") + end + # puts input else puts input end @@ -66,12 +84,50 @@ class Application when "/outbox" # receive from client if auth(env) - code, response = process input + code, response = parse input + else + code = 403 + response = "You are not allowed to POST to #{env["REQUEST_URI"]}." + end + + when "/follow" # receive from client + if auth(env) + input.split.each do |mention| + actor = actor(mention) + follow = { "@context" => "https://www.w3.org/ns/activitystreams", + "id" => File.join(SOCIAL_URL, "following", SecureRandom.uuid + ".json"), + "type" => "Follow", + "actor" => ACTOR, + "object" => actor } + save follow + puts(send follow, [actor]) + code = 200 + response = "OK" + end else code = 403 response = "You are not allowed to POST to #{env["REQUEST_URI"]}." end + when "/unfollow" # receive from client + if auth(env) + input.split.each do |mention| + actor = actor(mention) + Dir["following/*.json"].each do |f| + follow = JSON.parse(File.read(f)) + puts follow + if follow["object"] == actor + undo = { "@context" => "https://www.w3.org/ns/activitystreams", + "id" => File.join(SOCIAL_URL + "#undo", SecureRandom.uuid), + "type" => "Undo", + "actor" => ACTOR, + "object" => follow } + send undo, [actor] + FileUtils.rm f + end + end + end + end end when 'GET' @@ -106,7 +162,7 @@ class Application [code, { "Content-Type" => type }, [response]] end - def process input + def parse input date = Time.now.strftime("%Y-%m-%dT%H:%M:%S") # TODO media attachments, hashtags note = { @@ -173,30 +229,17 @@ class Application [type, response] end - def actor account - account = account.sub(/^@/, '').chomp - user, server = account.split("@") - header = { 'Accept' => "application/jrd+json" } - uri = URI("https://" + server + "/.well-known/webfinger?resource=acct:#{account}") - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - request = Net::HTTP::Get.new(uri.request_uri, header) - response = http.request(request) - JSON.parse(response.body)["links"].select { |l| l["rel"] == "self" }[0]["href"] - end - - def path object - object["id"].sub(SOCIAL_URL, '').sub('/', '') - end - - def save object - path = path object - FileUtils.mkdir_p File.dirname(path) - File.open(path, "w+") { |f| f.puts object.to_json } + def actor mention + mention = mention.sub(/^@/, '').chomp + user, server = mention.split("@") + get("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", + "application/jrd+json")["links"].select { |l| + l["rel"] == "self" + }[0]["href"] end def send object, urls - puts object, urls + # puts object, urls # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) responses = [] @@ -227,7 +270,7 @@ class Application responses << http.request(request) end - puts responses + # puts responses responses end @@ -245,6 +288,30 @@ class Application } end + def inbox uri + URI(get(uri)["inbox"]).request_uri + end + + def get url, accept = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' + uri = URI(url) + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + header = { 'Accept' => accept } + request = Net::HTTP::Get.new(uri.request_uri, header) + response = http.request(request) + JSON.parse(response.body) + end + + def path object + object["id"].sub(SOCIAL_URL, '').sub('/', '') + end + + def save object + path = path object + FileUtils.mkdir_p File.dirname(path) + File.open(path, "w+") { |f| f.puts object.to_json } + end + def verify env # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb # TODO verify digest @@ -274,20 +341,6 @@ class Application key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison) end - def get url - uri = URI(url) - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - header = { 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' } - request = Net::HTTP::Get.new(uri.request_uri, header) - response = http.request(request) - JSON.parse(response.body) - end - - def inbox uri - URI(get(uri)["inbox"]).request_uri - end - def auth env auth = Rack::Auth::Basic::Request.new(env) usr = File.read(".usr").chomp -- cgit v1.2.3