forge-fed.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. =begin NOTES
  2. NOTES:
  3. * new_note: value ":to => to_actor_url" breaks message symmetry
  4. * post_create_message: missing ":to => [ to_actor_url ]" breaks message symmetry
  5. * post_delete_message: missing ":id => delete_url" breaks message symmetry
  6. =end NOTES
  7. require 'http'
  8. require 'openssl'
  9. PVT_KEY_FILE = '../private.pem'
  10. KEY_ID = 'rsa-pub-key'
  11. PROTOCOL = 'https'
  12. HOSTNAME = 'c7fcb87a.ngrok.io'
  13. URL_PREFIX = PROTOCOL + '://' HOSTNAME '/'
  14. POST_HOST = 'mastodon.social'
  15. POST_PATH = '/inbox'
  16. POST_INBOX_URL = "https://#{POST_HOST}/#{POST_PATH}"
  17. DATE = Time.now.utc.httpdate
  18. POST_HEADERS = '(request-target) host date'
  19. AP_NS_URLS = [ "https://www.w3.org/ns/activitystreams" , "https://w3id.org/security/v1" ]
  20. AP_CONTEXT = { :@context => AP_NS_URLS }
  21. AP_ACCEPT_TYPE = 'Accept'
  22. AP_CREATE_TYPE = 'Create'
  23. AP_DELETE_TYPE = 'Delete'
  24. AP_FOLLOW_TYPE = 'Follow'
  25. AP_NOTE_TYPE = 'Note'
  26. AP_UNDO_TYPE = 'Undo'
  27. def new_note note_url , from_actor_url , to_actor_url , reply_to_url
  28. {
  29. :id => note_url ,
  30. :type => AP_NOTE_TYPE ,
  31. :published => DATE ,
  32. :attributedTo => from_actor_url ,
  33. :to => to_actor_url ,
  34. :inReplyTo => reply_to_url ,
  35. :content => '<p>Hello world</p>'
  36. }
  37. end
  38. def new_follow follow_url , from_actor_url , to_actor_url , follow_target_url
  39. {
  40. :id => follow_url ,
  41. :type => AP_FOLLOW_TYPE ,
  42. :actor => from_actor_url ,
  43. :to => [ to_actor_url ] ,
  44. :object => follow_target_url
  45. }
  46. end
  47. def post_create_message post_url , create_url , from_actor_url , ap_dict
  48. ap_dict =
  49. {
  50. :id => create_url ,
  51. :type => AP_CREATE_TYPE ,
  52. :actor => from_actor_url ,
  53. :object => ap_dict
  54. }
  55. post post_url , ap_dict
  56. end
  57. def post_accept_message post_url , accept_url , from_actor_url , to_actor_url , ap_dict
  58. ap_dict =
  59. {
  60. :id => accept_url ,
  61. :type => AP_ACCEPT_TYPE ,
  62. :actor => from_actor_url ,
  63. :to => [ to_actor_url ] ,
  64. :object => ap_dict
  65. }
  66. post post_url , ap_dict
  67. end
  68. def post_undo_message post_url , undo_url , from_actor_url , to_actor_url , ap_dict
  69. ap_dict =
  70. {
  71. :id => undo_url ,
  72. :type => AP_UNDO_TYPE ,
  73. :actor => from_actor_url ,
  74. :to => [ to_actor_url ] ,
  75. :object => ap_dict
  76. }
  77. post post_url , ap_dict
  78. end
  79. def post_delete_message post_url , from_actor_url , to_actor_url , ap_dict
  80. ap_dict =
  81. {
  82. :type => AP_DELETE_TYPE ,
  83. :actor => from_actor_url ,
  84. :to => [ to_actor_url ] ,
  85. :object => ap_dict
  86. }
  87. post post_url , ap_dict
  88. end
  89. def post post_url , ap_dict
  90. keypair = OpenSSL::PKey::RSA.new File.read PVT_KEY_FILE
  91. signed_string = "(request-target): post #{POST_PATH}\nhost: #{POST_HOST}\ndate: #{DATE}"
  92. raw_sig = keypair.sign OpenSSL::Digest::SHA256.new , signed_string
  93. signature = Base64.strict_encode64 raw_sig
  94. sig_header = "keyId=\"#{key_id}\",headers=\"#{POST_HEADERS}\",signature=\"#{signature}\""
  95. headers = { :Host => "#{POST_HOST}" , :Date => DATE , :Signature => sig_header }
  96. post_body = (ap_dict.merge AP_CONTEXT).to_json
  97. (HTTP.headers headers).post post_url , :body => post_body
  98. end
  99. =begin POST_NEW_NOTE
  100. actor_id = 'alice@' + HOSTNAME
  101. author_id = 'bob@' + HOSTNAME
  102. actor_url = URL_PREFIX + actor_id
  103. author_url = URL_PREFIX + author_id
  104. create_url = URL_PREFIX + 'what-goes-here'
  105. note_url = URL_PREFIX + 'what-goes-here-too'
  106. reply_to_url = URL_PREFIX + 'note-id'
  107. key_id = URL_PREFIX + author_id + '#' + KEY_ID
  108. inbox_url = URL_PREFIX + actor_id + POST_PATH
  109. ap_note = new_note note_url , author_url , reply_to_url , actor_url
  110. post_create_message POST_INBOX_URL , create_url , actor_url , ap_note
  111. =end POST_NEW_NOTE