service.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. class Service < ActiveRecord::Base
  2. attr_accessible :provider, :name, :token, :secret, :refresh_token, :expires_at, :global, :options, :uid
  3. serialize :options, Hash
  4. belongs_to :user, :inverse_of => :services
  5. has_many :agents, :inverse_of => :service
  6. validates_presence_of :user_id, :provider, :name, :token
  7. before_destroy :disable_agents
  8. scope :available_to_user, lambda { |user| where("services.user_id = ? or services.global = true", user.id) }
  9. scope :by_name, lambda { |dir = 'desc'| order("services.name #{dir}") }
  10. def disable_agents(conditions = {})
  11. agents.where.not(conditions[:where_not] || {}).each do |agent|
  12. agent.service_id = nil
  13. agent.disabled = true
  14. agent.save!(validate: false)
  15. end
  16. end
  17. def toggle_availability!
  18. disable_agents(where_not: {user_id: self.user_id}) if global
  19. self.global = !self.global
  20. self.save!
  21. end
  22. def prepare_request
  23. if expires_at && Time.now > expires_at
  24. refresh_token!
  25. end
  26. end
  27. def refresh_token!
  28. response = HTTParty.post(endpoint, query: {
  29. type: 'refresh',
  30. client_id: oauth_key,
  31. client_secret: oauth_secret,
  32. refresh_token: refresh_token
  33. })
  34. data = JSON.parse(response.body)
  35. update(expires_at: Time.now + data['expires_in'], token: data['access_token'], refresh_token: data['refresh_token'].presence || refresh_token)
  36. end
  37. def endpoint
  38. client_options = "OmniAuth::Strategies::#{OmniAuth::Utils.camelize(self.provider)}".constantize.default_options['client_options']
  39. URI.join(client_options['site'], client_options['token_url'])
  40. end
  41. def oauth_key
  42. (config = Devise.omniauth_configs[provider.to_sym]) && config.args[0]
  43. end
  44. def oauth_secret
  45. (config = Devise.omniauth_configs[provider.to_sym]) && config.args[1]
  46. end
  47. def self.provider_specific_options(omniauth)
  48. case omniauth['provider'].to_sym
  49. when :'37signals'
  50. { user_id: omniauth['extra']['accounts'][0]['id'], name: omniauth['info']['name'] }
  51. else
  52. { name: omniauth['info']['nickname'] || omniauth['info']['name'] }
  53. end
  54. end
  55. def self.initialize_or_update_via_omniauth(omniauth)
  56. options = provider_specific_options(omniauth)
  57. find_or_initialize_by(provider: omniauth['provider'], uid: omniauth['uid'].to_s).tap do |service|
  58. service.assign_attributes token: omniauth['credentials']['token'],
  59. secret: omniauth['credentials']['secret'],
  60. name: options[:name],
  61. refresh_token: omniauth['credentials']['refresh_token'],
  62. expires_at: omniauth['credentials']['expires_at'] && Time.at(omniauth['credentials']['expires_at']),
  63. options: options
  64. end
  65. end
  66. end