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.

71 lines
1.7 KiB

  1. # frozen_string_literal: true
  2. class Pubsubhubbub::SubscribeService < BaseService
  3. URL_PATTERN = /\A#{URI.regexp(%w(http https))}\z/
  4. attr_reader :account, :callback, :secret,
  5. :lease_seconds, :domain
  6. def call(account, callback, secret, lease_seconds, verified_domain = nil)
  7. @account = account
  8. @callback = Addressable::URI.parse(callback).normalize.to_s
  9. @secret = secret
  10. @lease_seconds = lease_seconds
  11. @domain = verified_domain
  12. process_subscribe
  13. end
  14. private
  15. def process_subscribe
  16. case subscribe_status
  17. when :invalid_topic
  18. ['Invalid topic URL', 422]
  19. when :invalid_callback
  20. ['Invalid callback URL', 422]
  21. when :callback_not_allowed
  22. ['Callback URL not allowed', 403]
  23. when :valid
  24. confirm_subscription
  25. ['', 202]
  26. end
  27. end
  28. def subscribe_status
  29. if account.nil?
  30. :invalid_topic
  31. elsif !valid_callback?
  32. :invalid_callback
  33. elsif blocked_domain?
  34. :callback_not_allowed
  35. else
  36. :valid
  37. end
  38. end
  39. def confirm_subscription
  40. subscription = locate_subscription
  41. Pubsubhubbub::ConfirmationWorker.perform_async(subscription.id, 'subscribe', secret, lease_seconds)
  42. end
  43. def valid_callback?
  44. callback.present? && callback =~ URL_PATTERN
  45. end
  46. def blocked_domain?
  47. DomainBlock.blocked? Addressable::URI.parse(callback).host
  48. end
  49. def locate_subscription
  50. subscription = Subscription.find_by(account: account, callback_url: callback)
  51. if subscription.nil?
  52. subscription = Subscription.new(account: account, callback_url: callback)
  53. end
  54. subscription.domain = domain
  55. subscription.save!
  56. subscription
  57. end
  58. end