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.

77 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. validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
  15. enum state: [:idle, :pending, :accepted, :rejected]
  16. scope :enabled, -> { accepted }
  17. before_destroy :ensure_disabled
  18. alias enabled? accepted?
  19. def enable!
  20. activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
  21. payload = Oj.dump(follow_activity(activity_id))
  22. update!(state: :pending, follow_activity_id: activity_id)
  23. DeliveryFailureTracker.reset!(inbox_url)
  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. DeliveryFailureTracker.reset!(inbox_url)
  31. ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
  32. end
  33. private
  34. def follow_activity(activity_id)
  35. {
  36. '@context': ActivityPub::TagManager::CONTEXT,
  37. id: activity_id,
  38. type: 'Follow',
  39. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  40. object: ActivityPub::TagManager::COLLECTIONS[:public],
  41. }
  42. end
  43. def unfollow_activity(activity_id)
  44. {
  45. '@context': ActivityPub::TagManager::CONTEXT,
  46. id: activity_id,
  47. type: 'Undo',
  48. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  49. object: {
  50. id: follow_activity_id,
  51. type: 'Follow',
  52. actor: ActivityPub::TagManager.instance.uri_for(some_local_account),
  53. object: ActivityPub::TagManager::COLLECTIONS[:public],
  54. },
  55. }
  56. end
  57. def some_local_account
  58. @some_local_account ||= Account.representative
  59. end
  60. def ensure_disabled
  61. disable! if enabled?
  62. end
  63. end