service.rb 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. class Service < ActiveRecord::Base
  2. serialize :options, Hash
  3. belongs_to :user, inverse_of: :services
  4. has_many :agents, inverse_of: :service
  5. validates_presence_of :user_id, :provider, :name, :token
  6. before_destroy :disable_agents
  7. scope :available_to_user, lambda { |user| where("services.user_id = ? or services.global = true", user.id) }
  8. scope :by_name, lambda { |dir = 'desc'| order("services.name #{dir}") }
  9. def disable_agents(conditions = {})
  10. agents.where.not(conditions[:where_not] || {}).each do |agent|
  11. agent.service_id = nil
  12. agent.disabled = true
  13. agent.save!(validate: false)
  14. end
  15. end
  16. def toggle_availability!
  17. disable_agents(where_not: { user_id: self.user_id }) if global
  18. self.global = !self.global
  19. self.save!
  20. end
  21. def prepare_request
  22. if expires_at && Time.now > expires_at
  23. refresh_token!
  24. end
  25. end
  26. def refresh_token_parameters
  27. {
  28. grant_type: 'refresh_token',
  29. client_id: oauth_key,
  30. client_secret: oauth_secret,
  31. refresh_token:
  32. }
  33. end
  34. def refresh_token!
  35. response = HTTParty.post(endpoint, query: refresh_token_parameters)
  36. data = JSON.parse(response.body)
  37. update(expires_at: Time.now + data['expires_in'], token: data['access_token'],
  38. refresh_token: data['refresh_token'].presence || refresh_token)
  39. end
  40. def endpoint
  41. client_options = Devise.omniauth_configs[provider.to_sym].strategy_class.default_options['client_options']
  42. URI.join(client_options['site'], client_options['token_url'])
  43. end
  44. def oauth_key
  45. (config = Devise.omniauth_configs[provider.to_sym]) && config.args[0]
  46. end
  47. def oauth_secret
  48. (config = Devise.omniauth_configs[provider.to_sym]) && config.args[1]
  49. end
  50. def self.initialize_or_update_via_omniauth(omniauth)
  51. options = get_options(omniauth)
  52. find_or_initialize_by(provider: omniauth['provider'], uid: omniauth['uid'].to_s).tap do |service|
  53. service.attributes = {
  54. token: omniauth['credentials']['token'],
  55. secret: omniauth['credentials']['secret'],
  56. name: options[:name],
  57. refresh_token: omniauth['credentials']['refresh_token'],
  58. expires_at: omniauth['credentials']['expires_at'] && Time.at(omniauth['credentials']['expires_at']),
  59. options:
  60. }
  61. end
  62. end
  63. def self.register_options_provider(provider_name, &block)
  64. option_providers[provider_name] = block
  65. end
  66. def self.get_options(omniauth)
  67. option_providers.fetch(omniauth['provider'], option_providers['default']).call(omniauth)
  68. end
  69. @@option_providers = HashWithIndifferentAccess.new
  70. cattr_reader :option_providers
  71. register_options_provider('default') do |omniauth|
  72. { name: omniauth['info']['nickname'] || omniauth['info']['name'] }
  73. end
  74. register_options_provider('google') do |omniauth|
  75. {
  76. email: omniauth['info']['email'],
  77. name: "#{omniauth['info']['name']} <#{omniauth['info']['email']}>"
  78. }
  79. end
  80. end