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.

78 lines
2.2 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. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  25. end
  26. def disable!
  27. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  28. payload = Oj.dump(unfollow_activity(activity_id))
  29. update!(state: :idle, follow_activity_id: nil)
  30. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  31. end
  32. private
  33. def follow_activity(activity_id)
  34. {
  35. '@context': ActivityPub::TagManager::CONTEXT,
  36. id: activity_id,
  37. type: 'Follow',
  38. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  39. object: ActivityPub::TagManager::COLLECTIONS[:public],
  40. }
  41. end
  42. def unfollow_activity(activity_id)
  43. {
  44. '@context': ActivityPub::TagManager::CONTEXT,
  45. id: activity_id,
  46. type: 'Undo',
  47. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  48. object: {
  49. id: follow_activity_id,
  50. type: 'Follow',
  51. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  52. object: ActivityPub::TagManager::COLLECTIONS[:public],
  53. },
  54. }
  55. end
  56. def some_local_account
  57. @some_local_account ||= Account.local.find_by(suspended: false)
  58. end
  59. def ensure_disabled
  60. return unless enabled?
  61. disable!
  62. end
  63. end