闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.3 KiB

  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: relays
  5. #
  6. # id :bigint(8) not null, primary key
  7. # inbox_url :string default(""), not null
  8. # follow_activity_id :string
  9. # created_at :datetime not null
  10. # updated_at :datetime not null
  11. # state :integer default("idle"), not null
  12. #
  13. class Relay < ApplicationRecord
  14. PRESET_RELAY = 'https://relay.joinmastodon.org/inbox'
  15. validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
  16. enum state: [:idle, :pending, :accepted, :rejected]
  17. scope :enabled, -> { accepted }
  18. before_destroy :ensure_disabled
  19. alias enabled? accepted?
  20. def enable!
  21. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  22. payload = Oj.dump(follow_activity(activity_id))
  23. update!(state: :pending, follow_activity_id: activity_id)
  24. DeliveryFailureTracker.new(inbox_url).track_success!
  25. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  26. end
  27. def disable!
  28. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  29. payload = Oj.dump(unfollow_activity(activity_id))
  30. update!(state: :idle, follow_activity_id: nil)
  31. DeliveryFailureTracker.new(inbox_url).track_success!
  32. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  33. end
  34. private
  35. def follow_activity(activity_id)
  36. {
  37. '@context': ActivityPub::TagManager::CONTEXT,
  38. id: activity_id,
  39. type: 'Follow',
  40. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  41. object: ActivityPub::TagManager::COLLECTIONS[:public],
  42. }
  43. end
  44. def unfollow_activity(activity_id)
  45. {
  46. '@context': ActivityPub::TagManager::CONTEXT,
  47. id: activity_id,
  48. type: 'Undo',
  49. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  50. object: {
  51. id: follow_activity_id,
  52. type: 'Follow',
  53. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  54. object: ActivityPub::TagManager::COLLECTIONS[:public],
  55. },
  56. }
  57. end
  58. def some_local_account
  59. @some_local_account ||= Account.representative
  60. end
  61. def ensure_disabled
  62. return unless enabled?
  63. disable!
  64. end
  65. end