summaryrefslogtreecommitdiff
path: root/application.rb
diff options
context:
space:
mode:
Diffstat (limited to 'application.rb')
-rw-r--r--application.rb155
1 files changed, 155 insertions, 0 deletions
diff --git a/application.rb b/application.rb
new file mode 100644
index 0000000..6abf490
--- /dev/null
+++ b/application.rb
@@ -0,0 +1,155 @@
+require 'json'
+require 'net/http'
+require 'uri'
+
+USER = "pdp8"
+WWW_DOMAIN = "pdp8.info"
+WWW_URL = "https://#{WWW_DOMAIN}"
+SOCIAL_DOMAIN = "social.#{WWW_DOMAIN}"
+
+ACCOUNT = "#{USER}@#{SOCIAL_DOMAIN}"
+SOCIAL_URL = "https://#{SOCIAL_DOMAIN}"
+ACTOR = URI.join(SOCIAL_URL, USER)
+
+MATRIX = "@#{USER}:matrix.#{WWW_DOMAIN}"
+
+class Application
+ def call(env)
+ code = 404
+ type = "application/activity+json"
+
+ case env['REQUEST_METHOD']
+
+ when 'POST'
+ case env["REQUEST_URI"]
+
+ when "/inbox"
+ type = "text/plain"
+ 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.decode64(signature_header['signature'])
+ 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)
+ input = JSON.parse(env["rack.input"].gets)
+ code = 200
+ response = "OK"
+ else
+ code = 401
+ response = 'Request signature could not be verified'
+ end
+
+ end
+
+ when 'GET'
+
+ 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
+ }
+ ]
+ }
+
+ when "/#{USER}"
+ 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"
+ code = 200
+ 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"
+ end
+
+ end
+ [code, { "Content-Type" => type }, [response.to_json]]
+ end
+end