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