summaryrefslogtreecommitdiff
path: root/application.rb
diff options
context:
space:
mode:
Diffstat (limited to 'application.rb')
-rw-r--r--application.rb184
1 files changed, 72 insertions, 112 deletions
diff --git a/application.rb b/application.rb
index 7618855..6e700fd 100644
--- a/application.rb
+++ b/application.rb
@@ -14,6 +14,9 @@ ACTOR = URI.join(SOCIAL_URL, USER)
MATRIX = "@#{USER}:matrix.#{WWW_DOMAIN}"
+OUTBOX = File.join(File.dirname(__FILE__), "outbox")
+INBOX = File.join(File.dirname(__FILE__), "inbox")
+
class Application
def call(env)
code = 404
@@ -24,41 +27,21 @@ class Application
when 'POST'
case env["REQUEST_URI"]
- when "/inbox"
- type = "text/plain"
- signature_header = {}
- if env["HTTP_SIGNATURE"].split(',')
- env["HTTP_SIGNATURE"].split(',').each do |pair|
- k, v = pair.split('=')
- signature_header[k] = v.gsub('"', '')
- end
- key_id = signature_header['keyId']
- headers = signature_header['headers']
- signature = Base64.urlsafe_decode64(signature_header['signature'].encode("ascii-8bit"))
- uri = URI(key_id)
- res = Net::HTTP.get_response(uri)
- actor = JSON.parse(res.body)
- key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem'])
-
- comparison_string = headers.split(' ').map do |signed_header_name|
- if signed_header_name == '(request-target)'
- '(request-target): post /inbox'
- else
- "#{signed_header_name}: #{env["HTTP_" + signed_header_name.upcase]}"
- end
- end.join("\n")
- if key.verify(OpenSSL::Digest::SHA256.new, signature, comparison_string.encode("ascii-8bit"))
- input = JSON.parse(env["rack.input"].gets)
- # p input
- code = 200
- response = "OK"
- else
- code = 401
- response = 'Request signature could not be verified'
- end
+ when "/inbox" # receive from server
+ if verify(env)
+ input = JSON.parse(env["rack.input"].gets)
+ # p input["type"]
+ code = 200
+ response = "OK"
else
code = 401
- response = 'Request signature could not be verified'
+ response = "not verified"
+ end
+
+ when "/outbox"
+ input = JSON.parse(env["rack.input"].gets)
+ case input["type"]
+ when "Create"
end
end
@@ -68,95 +51,72 @@ class Application
case env["REQUEST_URI"]
when "/.well-known/webfinger?resource=acct:#{ACCOUNT}"
- code = 200
type = "application/jrd+json"
- response = {
- "subject" => "acct:#{ACCOUNT}",
- "links" => [
- {
- "rel" => "self",
- "type" => "application/activity+json",
- "href" => ACTOR
- }
- ]
- }
+ response = File.read("webfinger")
+ code = 200
when "/#{USER}"
+ response = File.read("pdp8")
code = 200
- response = {
- "@context" => ["https://www.w3.org/ns/activitystreams"],
- "id" => ACTOR,
- "type" => "Person",
- "preferredUsername" => USER,
- "name" => USER,
- "inbox" => URI.join(SOCIAL_URL, "inbox"),
- "outbox" => URI.join(SOCIAL_URL, "outbox"),
- "following" => URI.join(SOCIAL_URL, "following"),
- "followers" => URI.join(SOCIAL_URL, "followers"),
- "liked" => URI.join(SOCIAL_URL, "liked"),
- "icon" => {
- "type" => "Image",
- "url" => "https://pdp8.info/pdp8.png"
- },
- "attachment": [
- {
- "type": "PropertyValue",
- "name": "Web",
- "value": "<a href=\"#{WWW_URL}\">#{WWW_DOMAIN}</a>"
- },
- {
- "type": "PropertyValue",
- "name": "Fediverse",
- "value": "<a rel=\"me\" href=\"#{ACTOR}\">@#{ACCOUNT}</a>"
- },
- {
- "type": "PropertyValue",
- "name": "Matrix",
- "value": "<a rel=\"me\" href=\"https://matrix.to/#/#{MATRIX}\">#{MATRIX}</a>"
- }
- ],
- "publicKey" => {
- "@context" => "https://w3id.org/security/v1",
- "@type" => "Key",
- "id" => "#{ACTOR}#main-key",
- "owner" => ACTOR,
- "publicKeyPem" => File.read("public.pem")
- }
- }
when "/outbox"
+ response = ordered_collection OUTBOX
code = 200
+
+ when "/inbox"
type = "application/activity+json"
- response = {
- "@context" => "https://www.w3.org/ns/activitystreams",
- "summary" => "",
- "type" => "OrderedCollection",
- "totalItems" => 2,
- # TODO generate items from src/www
- "orderedItems" => [
- {
- "type" => "Note",
- "name" => "A Simple Note",
- "tag" => [
- {
- "type" => "Hashtag",
- "name" => "#activitypub",
- "href" => "https://s3lph.me/activitypub/tags/activitypub"
- },
- ]
- },
- {
- "type" => "Note",
- "name" => "Another Simple Note"
- }
- ]
- }
- when "/following"
- when "/followers"
- when "/liked"
+ response = ordered_collection INBOX
+ code = 200
+
+ # when "/following"
+ # when "/followers"
+ # when "/liked"
end
end
- [code, { "Content-Type" => type }, [response.to_json]]
+ [code, { "Content-Type" => type }, [response]]
+ end
+
+ def ordered_collection dir
+ posts = Dir[File.join(dir, "*.json")].sort.reverse.collect { |f| p f; JSON.parse(File.read f) }
+ {
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "summary" => "pdp8 outbox",
+ "type" => "OrderedCollection",
+ "totalItems" => posts.size,
+ "orderedItems" => posts,
+ }.to_json
+ end
+
+ def verify(env)
+ begin
+ signature_header = {}
+ env["HTTP_SIGNATURE"].split(',').each do |pair|
+ k, v = pair.split('=')
+ signature_header[k] = v.gsub('"', '')
+ end
+ key_id = signature_header['keyId']
+ headers = signature_header['headers']
+ signature = Base64.urlsafe_decode64(signature_header['signature'].encode("ascii-8bit"))
+ uri = URI(key_id)
+ res = Net::HTTP.get_response(uri)
+ actor = JSON.parse(res.body)
+ key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem'])
+
+ comparison_string = headers.split(' ').map do |signed_header_name|
+ if signed_header_name == '(request-target)'
+ '(request-target): post /inbox'
+ else
+ "#{signed_header_name}: #{env["HTTP_" + signed_header_name.upcase]}"
+ end
+ end.join("\n")
+ if key.verify(OpenSSL::Digest::SHA256.new, signature, comparison_string.encode("ascii-8bit"))
+ true
+ else
+ false
+ end
+ rescue
+ false
+ end
end
end