diff options
-rw-r--r-- | application.rb | 9 | ||||
-rw-r--r-- | client.rb | 79 | ||||
-rw-r--r-- | helpers.rb | 10 | ||||
-rw-r--r-- | server.rb | 6 |
4 files changed, 39 insertions, 65 deletions
diff --git a/application.rb b/application.rb index 8a62fdd..a03d98c 100644 --- a/application.rb +++ b/application.rb @@ -3,6 +3,8 @@ require 'uri' require 'base64' require 'digest/sha2' +require 'rack/protection' +# require 'rack/contrib' require 'sinatra' SOCIAL_DIR = '/srv/social/' @@ -27,7 +29,14 @@ FOLLOWERS_URL = 'https://social.pdp8.info/followers' CONTENT_TYPE = 'application/activity+json' # CONTENT_TYPE = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' +use Rack::Protection +# use Rack::MailExceptions do |mail| +# mail.to 'info@pdp8.info' +# mail.smtp false +# end + enable :sessions +set :environment, :production set :session_secret, File.read('.secret').chomp set :default_content_type, CONTENT_TYPE set :port, 9292 @@ -1,34 +1,8 @@ -# frozen_string_literal: true - # client-server - -['/inbox/threads', '/outbox/threads'].each do |path| +['/inbox/object', '/outbox/object'].each do |path| get path do protected! - box = path.sub('/', '').sub('/threads', '') - collection = Dir[File.join(box, 'object', '*', '*.json')].collect { |f| JSON.parse(File.read(f)) } - threads = [] - collection.collect! do |object| - object.is_a?(String) && object.match(/^http/) ? fetch(object) : object - end - collection.compact! - collection.each do |object| - object['mention'] = mention object['attributedTo'] - if object['type'] == 'Audio' - audio_url = object['url'].select { |url| url['mediaType'].match('audio') }[0] - object['attachment'] = [{ 'url' => audio_url['href'], 'mediaType' => audio_url['mediaType'] }] - end - object['replies'] = [] - threads << object if object['inReplyTo'].nil? || collection.select do |o| - o['id'] == object['inReplyTo'] - end.empty? - end - collection.each do |object| - collection.select { |o| o['id'] == object['inReplyTo'] }.each do |o| - o['replies'] << object - end - end - threads.sort_by { |o| o['published'] }.to_json + Dir[File.join(path.sub('/', ''), '*', '*.json')].collect { |f| JSON.load_file(f) }.to_json end end @@ -36,6 +10,24 @@ post '/delete' do protected! params['id'].each do |id| file = find_file id + if file.match(%r{outbox/}) # find/delete activity + + Dir[File.join 'outbox', 'announce', '*'].each do |announce_file| + announce = JSON.load_file(announce_file) + next unless announce['object']['id'] == id + + outbox 'Undo', announce, announce['to'] + FileUtils.rm(announce_file) + end + Dir[File.join 'outbox', 'create', '*'].each do |create_file| + create = JSON.load_file(create_file) + next unless create['object']['id'] == id + + object = JSON.load_file(file) + outbox 'Delete', object, object['to'] + FileUtils.rm(create_file) + end + end FileUtils.rm(file) if File.exist? file end 200 @@ -51,9 +43,8 @@ end post '/unfollow' do protected! params['id'] = actor params['mention'] if params['mention'] - following = Dir[File.join(OUTBOX[:dir], 'follow', '*.json')].collect { |f| JSON.parse(File.read(f)) } + following = Dir[File.join(OUTBOX[:dir], 'follow', '*.json')].collect { |f| JSON.load_file(f) } activity = following.find { |a| a['object'] == params['id'] } - # activity ||= save_activity({ 'type' => 'Follow', 'actor' => ACTOR, 'object' => params['id'] }, OUTBOX) # recreate activity for old/deleted follows outbox 'Undo', activity, [params['id']] update_collection FOLLOWING, params['id'], true 200 @@ -62,8 +53,9 @@ end post '/share' do # TODO protected! src = find_file params['id'] - object = JSON.parse(File.read(src)) - recipients = public + object = JSON.load_file(src) + recipients = ['https://www.w3.org/ns/activitystreams#Public'] + recipients += JSON.load_file(FOLLOWERS)['orderedItems'] recipients << object['attributedTo'] outbox 'Announce', object, recipients dest = src.sub('inbox/', 'outbox/') @@ -81,27 +73,4 @@ helpers do def protected! halt 403 unless session['client'] end - - def public - recipients = ['https://www.w3.org/ns/activitystreams#Public'] - recipients += JSON.parse(File.read(FOLLOWERS))['orderedItems'] - recipients.delete ACTOR - recipients.uniq - end - - def parse_follow(follow) - case follow - when /^#/ - actor = "https://relay.fedi.buzz/tag/#{follow.sub(/^#/, '')}" - mention = follow - when /^http/ - actor = follow - mention = mention(actor) - when /^@*\w+@\w+/ - mention = follow - actor = actor(follow) - return 502 unless actor - end - [actor, mention] - end end @@ -46,7 +46,7 @@ helpers do tag_path = File.join(TAGS[:dir], tag['name'].sub('#', '')) + '.json' tag_collection = if File.exist? tag_path - JSON.parse(File.read(tag_path)) + JSON.load_file(tag_path) else { '@context' => 'https://www.w3.org/ns/activitystreams', @@ -92,8 +92,7 @@ helpers do begin uri = URI(url) rescue StandardError => e - p url - p e + p url, e return nil end httpdate = Time.now.utc.httpdate @@ -112,8 +111,7 @@ helpers do if $CHILD_STATUS.success? response else - p url - p response + p url, response nil end end @@ -172,7 +170,7 @@ helpers do def find_file(id) Dir[File.join('*', 'object', '*', '*.json')].find do |f| - JSON.parse(File.read(f))['id'] == id + JSON.load_file(f)['id'] == id end end end @@ -1,5 +1,3 @@ -# frozen_string_literal: true - # server-server post '/inbox' do request.body.rewind # in case someone already read it @@ -26,7 +24,7 @@ end get '/outbox' do files = Dir[File.join('outbox', 'create', '*.json')] + Dir[File.join('outbox', 'announce', '*.json')] - activities = files.collect { |f| JSON.parse(File.read(f)) } + activities = files.collect { |f| JSON.load_file(f) } ids = activities.sort_by { |a| a['published'] }.collect { |a| a['id'] } { '@context' => 'https://www.w3.org/ns/activitystreams', 'id' => 'https://social.pdp8.info/outbox', @@ -155,7 +153,7 @@ helpers do next if [ACTOR, 'https://www.w3.org/ns/activitystreams#Public'].include? url if url == FOLLOWERS_URL - JSON.parse(File.read(FOLLOWERS))['orderedItems'].each do |follower| + JSON.load_file(FOLLOWERS)['orderedItems'].each do |follower| inboxes << actor_inbox(follower) end next |