summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--activitypub.rb166
-rw-r--r--views/index.erb12
2 files changed, 101 insertions, 77 deletions
diff --git a/activitypub.rb b/activitypub.rb
index a340291..ba763e3 100644
--- a/activitypub.rb
+++ b/activitypub.rb
@@ -1,8 +1,7 @@
# TODO
-# delete all/thread
-# anchors (return after delete)
+# follow request confirmation
+# anchors (return after archive)
# boost
-# archive
# federation
# client post media
# test with pleroma etc
@@ -26,13 +25,8 @@ set :session_secret, File.read(".secret").chomp
set :default_content_type, 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
set :port, 9292
-before "/" do
- if request.request_method == "POST"
- halt 400 unless verify_signature(request.env)
- end
-end
-
post "/inbox" do # server-server
+ verify!
request.body.rewind # in case someone already read it
body = request.body.read
action = JSON.parse body
@@ -67,8 +61,9 @@ post "/inbox" do # server-server
end
end
- #else
- #p body
+ else
+ p "Unknown action: #{action['type']}"
+ p body
end
end
@@ -116,12 +111,24 @@ post "/outbox" do # client-server
recipients.each { |r| send_signed create, r }
end
+post "/archive/*" do
+ protected!
+ FileUtils.mv params['splat'][0], "archive/"
+ redirect to("/")
+end
+
post "/delete/*" do
protected!
FileUtils.rm params['splat'][0]
redirect to("/")
end
+post "/delete" do
+ protected!
+ FileUtils.rm Dir["inbox/*.json"]
+ redirect to("/")
+end
+
post "/follow/*" do
protected!
mention = params['splat'][0]
@@ -167,9 +174,60 @@ get "/.well-known/webfinger" do
end
end
+get "/archive", :provides => 'html' do
+ protected!
+ dir_html "archive"
+end
+
get "/", :provides => 'html' do
protected!
- items = Dir['./inbox/*.json'].sort.collect do |file|
+ dir_html "inbox"
+end
+
+["/outbox","/following","/followers"].each do |path|
+ get path do
+ ordered_collection(path).to_json
+ end
+end
+
+helpers do
+
+ def protected!
+ redirect("/login.html") unless session['client']
+ end
+
+ def verify!
+ # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb
+ # TODO verify digest
+ signature_params = {}
+ request.env["HTTP_SIGNATURE"].split(',').each do |pair|
+ k, v = pair.split('=')
+ signature_params[k] = v.gsub('"', '')
+ end
+
+ key_id = signature_params['keyId']
+ headers = signature_params['headers']
+ signature = Base64.decode64(signature_params['signature'])
+
+ actor = fetch key_id
+ key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem'])
+
+ comparison = headers.split(' ').map do |signed_params_name|
+ if signed_params_name == '(request-target)'
+ '(request-target): post /inbox'
+ elsif signed_params_name == 'content-type'
+ "#{signed_params_name}: #{request.env["CONTENT_TYPE"]}"
+ else
+ "#{signed_params_name}: #{request.env["HTTP_" + signed_params_name.upcase]}"
+ end
+ end.join("\n")
+
+ halt 400 unless key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison)
+ end
+end
+
+def dir_html dir
+ items = Dir[File.join(dir, '*.json')].sort.collect do |file|
item = JSON.parse(File.read(file))
mention = mention(item['attributedTo'])
following_path = File.join('public', 'following', mention + '.json')
@@ -185,12 +243,11 @@ get "/", :provides => 'html' do
:replies => []
}
end.compact
- @inbox = []
+ threads = []
items.each do |i|
if i[:parent].nil? or items.select{|it| it[:id] == i[:parent] }.empty?
- @inbox << i
+ threads << i
else
- #p i
items.select{|it| it[:id] == i[:parent] }.each{|it| it[:replies] << i}
end
end
@@ -199,29 +256,22 @@ get "/", :provides => 'html' do
<head>
<link rel='stylesheet' type='text/css' href='/style.css'>
</head>
- <body>"
- @inbox.each do |item|
- html += html(item)
+ <body>
+ <h1>#{dir}</h1>
+ "
+ threads.each do |item|
+ html << item_html(item,dir)
end
- html+=' </body>
- </html>'
- #erb :index
+ html << "
+ <form action='delete' method='post'>
+ <button>Delete all</button>
+ </form>
+ </body>
+ </html>" if dir == "inbox"
html
end
-["/outbox","/following","/followers"].each do |path|
- get path do
- ordered_collection(path).to_json
- end
-end
-
-helpers do
- def protected!
- redirect("/login.html") unless session['client']
- end
-end
-
-def html item, indent=2
+def item_html item, dir, indent=2
html = "
<div style='margin-left:#{indent}em'>
<b><a href='#{ item[:actor_url] }', target='_blank'>#{ item[:mention] }</a></b>&nbsp;
@@ -229,9 +279,22 @@ def html item, indent=2
<button>#{ item[:follow].capitalize }</button>
</form>
&nbsp;
- <form action='#{ File.join 'delete', item[:file] }' method='post'>
- <button>Delete</button>
- </form>
+ "
+ case dir
+ when "inbox"
+ html << "
+ <form action='#{ File.join 'archive', item[:file] }' method='post'>
+ <button>Archive</button>
+ </form>
+ "
+ when "archive"
+ html << "
+ <form action='#{ File.join 'delete', item[:file] }' method='post'>
+ <button>Delete</button>
+ </form>
+ "
+ end
+ html << "
#{ item[:content].gsub('<br />','') }"
if item[:attachment]
item[:attachment].each do |att|
@@ -252,7 +315,7 @@ def html item, indent=2
html << "
</div>"
item[:replies].each do |r|
- html << html(r,indent+4)
+ html << item_html(r,dir,indent+4)
end
html
@@ -363,33 +426,6 @@ def inbox uri
end
def verify_signature env
- # https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb
- # TODO verify digest
- #begin
- signature_params = {}
- env["HTTP_SIGNATURE"].split(',').each do |pair|
- k, v = pair.split('=')
- signature_params[k] = v.gsub('"', '')
- end
-
- key_id = signature_params['keyId']
- headers = signature_params['headers']
- signature = Base64.decode64(signature_params['signature'])
-
- actor = fetch key_id
- key = OpenSSL::PKey::RSA.new(actor['publicKey']['publicKeyPem'])
-
- comparison = headers.split(' ').map do |signed_params_name|
- if signed_params_name == '(request-target)'
- '(request-target): post /inbox'
- elsif signed_params_name == 'content-type'
- "#{signed_params_name}: #{env["CONTENT_TYPE"]}"
- else
- "#{signed_params_name}: #{env["HTTP_" + signed_params_name.upcase]}"
- end
- end.join("\n")
-
- key.verify(OpenSSL::Digest.new('SHA256'), signature, comparison)
#rescue
#false
#end
diff --git a/views/index.erb b/views/index.erb
deleted file mode 100644
index 3a245a9..0000000
--- a/views/index.erb
+++ /dev/null
@@ -1,12 +0,0 @@
- <!DOCTYPE html>
- <html lang='en'>
- <head>
- <link rel='stylesheet' type='text/css' href='/style.css'>
- </head>
- <body>
- <% @inbox.each do |item| %>
- <%= erb :item %>
- <hr>
- <% end %>
- </body>
- </html>