闭社主体 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.

88 lines
1.9 KiB

  1. # frozen_string_literal: true
  2. class Pubsubhubbub::ConfirmationWorker
  3. include Sidekiq::Worker
  4. include RoutingHelper
  5. sidekiq_options queue: 'push', retry: false
  6. attr_reader :subscription, :mode, :secret, :lease_seconds
  7. def perform(subscription_id, mode, secret = nil, lease_seconds = nil)
  8. @subscription = Subscription.find(subscription_id)
  9. @mode = mode
  10. @secret = secret
  11. @lease_seconds = lease_seconds
  12. process_confirmation
  13. end
  14. private
  15. def process_confirmation
  16. prepare_subscription
  17. confirm_callback
  18. logger.debug "Confirming PuSH subscription for #{subscription.callback_url} with challenge #{challenge}: #{callback_response_body}"
  19. update_subscription
  20. end
  21. def update_subscription
  22. if successful_subscribe?
  23. subscription.save!
  24. elsif successful_unsubscribe?
  25. subscription.destroy!
  26. end
  27. end
  28. def successful_subscribe?
  29. subscribing? && response_matches_challenge?
  30. end
  31. def successful_unsubscribe?
  32. (unsubscribing? && response_matches_challenge?) || !subscription.confirmed?
  33. end
  34. def response_matches_challenge?
  35. callback_response_body == challenge
  36. end
  37. def subscribing?
  38. mode == 'subscribe'
  39. end
  40. def unsubscribing?
  41. mode == 'unsubscribe'
  42. end
  43. def confirm_callback
  44. @_confirm_callback ||= callback_get_with_params
  45. end
  46. def callback_get_with_params
  47. Request.new(:get, subscription.callback_url, params: callback_params).perform
  48. end
  49. def callback_response_body
  50. confirm_callback.body.to_s
  51. end
  52. def callback_params
  53. {
  54. 'hub.topic': account_url(subscription.account, format: :atom),
  55. 'hub.mode': mode,
  56. 'hub.challenge': challenge,
  57. 'hub.lease_seconds': subscription.lease_seconds,
  58. }
  59. end
  60. def prepare_subscription
  61. subscription.secret = secret
  62. subscription.lease_seconds = lease_seconds
  63. subscription.confirmed = true
  64. end
  65. def challenge
  66. @_challenge ||= SecureRandom.hex
  67. end
  68. end