2019-05-11 17:53:37 +02:00
|
|
|
require 'excon'
|
|
|
|
|
2019-05-31 09:54:11 +02:00
|
|
|
class CustomWizard::Api::Authorization
|
2019-05-30 07:04:34 +02:00
|
|
|
include ActiveModel::SerializerSupport
|
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
attr_accessor :api_name,
|
|
|
|
:authorized,
|
2019-05-30 07:04:34 +02:00
|
|
|
:auth_type,
|
|
|
|
:auth_url,
|
|
|
|
:token_url,
|
|
|
|
:client_id,
|
|
|
|
:client_secret,
|
|
|
|
:auth_params,
|
|
|
|
:access_token,
|
|
|
|
:refresh_token,
|
|
|
|
:token_expires_at,
|
|
|
|
:token_refresh_at,
|
|
|
|
:code,
|
|
|
|
:username,
|
|
|
|
:password
|
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
def initialize(api_name, data={})
|
|
|
|
@api_name = api_name
|
2019-05-30 07:04:34 +02:00
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
data.each do |k, v|
|
|
|
|
self.send "#{k}=", v if self.respond_to?(k)
|
2019-05-30 07:04:34 +02:00
|
|
|
end
|
2019-05-15 08:54:32 +02:00
|
|
|
end
|
|
|
|
|
2019-05-30 07:04:34 +02:00
|
|
|
def authorized
|
|
|
|
@authorized ||= @access_token && @token_expires_at.to_datetime > Time.now
|
2019-05-15 08:54:32 +02:00
|
|
|
end
|
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
def self.set(api_name, new_data = {})
|
|
|
|
data = self.get(api_name, data_only: true) || {}
|
2019-05-11 17:53:37 +02:00
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
new_data.each do |k, v|
|
|
|
|
data[k.to_sym] = v
|
2019-05-30 07:04:34 +02:00
|
|
|
end
|
2019-05-11 17:53:37 +02:00
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
PluginStore.set("custom_wizard_api_#{api_name}", 'authorization', data)
|
2019-06-02 12:54:31 +02:00
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
self.get(api_name)
|
2019-06-02 12:54:31 +02:00
|
|
|
end
|
2019-05-11 17:53:37 +02:00
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
def self.get(api_name, opts = {})
|
|
|
|
if data = PluginStore.get("custom_wizard_api_#{api_name}", 'authorization')
|
|
|
|
if opts[:data_only]
|
|
|
|
data
|
|
|
|
else
|
|
|
|
self.new(api_name, data)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
2019-05-11 17:53:37 +02:00
|
|
|
end
|
|
|
|
|
2019-06-03 04:49:54 +02:00
|
|
|
def self.remove(api_name)
|
|
|
|
PluginStore.remove("custom_wizard_api_#{api_name}", "authorization")
|
2019-05-11 17:53:37 +02:00
|
|
|
end
|
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
def self.get_header_authorization_string(name)
|
|
|
|
protocol = authentication_protocol(name)
|
|
|
|
raise Discourse::InvalidParameters.new(:name) unless protocol.present?
|
2019-05-15 08:54:32 +02:00
|
|
|
raise Discourse::InvalidParameters.new(:protocol) unless [BASIC_AUTH, OAUTH2_AUTH].include? protocol
|
|
|
|
|
|
|
|
if protocol = BASIC_AUTH
|
2019-06-02 12:54:31 +02:00
|
|
|
username = username(name)
|
2019-05-15 08:54:32 +02:00
|
|
|
raise Discourse::InvalidParameters.new(:username) unless username.present?
|
2019-06-02 12:54:31 +02:00
|
|
|
password = password(name)
|
2019-05-15 08:54:32 +02:00
|
|
|
raise Discourse::InvalidParameters.new(:password) unless password.present?
|
|
|
|
authorization_string = (username + ":" + password).chomp
|
|
|
|
"Basic #{Base64.strict_encode64(authorization_string)}"
|
|
|
|
else
|
2019-05-15 09:09:48 +02:00
|
|
|
# must be OAUTH2
|
2019-06-02 12:54:31 +02:00
|
|
|
access_token = access_token(name)
|
2019-05-15 09:09:48 +02:00
|
|
|
raise Discourse::InvalidParameters.new(access_token) unless access_token.present?
|
|
|
|
"Bearer #{access_token}"
|
2019-05-15 08:54:32 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
def self.get_token(name)
|
|
|
|
authorization = CustomWizard::Api::Authorization.get(name)
|
2019-05-30 07:04:34 +02:00
|
|
|
|
2019-05-11 17:53:37 +02:00
|
|
|
body = {
|
2019-05-30 07:04:34 +02:00
|
|
|
client_id: authorization.client_id,
|
|
|
|
client_secret: authorization.client_secret,
|
|
|
|
code: authorization.code,
|
2019-05-11 17:53:37 +02:00
|
|
|
grant_type: 'authorization_code',
|
2019-06-02 12:54:31 +02:00
|
|
|
redirect_uri: Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
|
2019-05-11 17:53:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
result = Excon.post(
|
2019-05-30 07:04:34 +02:00
|
|
|
authorization.token_url,
|
2019-05-11 17:53:37 +02:00
|
|
|
:headers => {
|
|
|
|
"Content-Type" => "application/x-www-form-urlencoded"
|
|
|
|
},
|
|
|
|
:body => URI.encode_www_form(body)
|
|
|
|
)
|
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
self.handle_token_result(name, result)
|
2019-05-11 17:53:37 +02:00
|
|
|
end
|
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
def self.refresh_token(name)
|
|
|
|
authorization = CustomWizard::Api::Authorization.get(name)
|
2019-05-30 07:04:34 +02:00
|
|
|
|
2019-05-11 17:53:37 +02:00
|
|
|
body = {
|
|
|
|
grant_type: 'refresh_token',
|
2019-05-30 07:04:34 +02:00
|
|
|
refresh_token: authorization.refresh_token
|
2019-05-11 17:53:37 +02:00
|
|
|
}
|
|
|
|
|
2019-05-30 07:04:34 +02:00
|
|
|
authorization_string = authorization.client_id + ':' + authorization.client_secret
|
2019-05-11 17:53:37 +02:00
|
|
|
|
|
|
|
result = Excon.post(
|
2019-05-30 07:04:34 +02:00
|
|
|
authorization.token_url,
|
2019-05-11 17:53:37 +02:00
|
|
|
:headers => {
|
|
|
|
"Content-Type" => "application/x-www-form-urlencoded",
|
|
|
|
"Authorization" => "Basic #{Base64.strict_encode64(authorization_string)}"
|
|
|
|
},
|
|
|
|
:body => URI.encode_www_form(body)
|
|
|
|
)
|
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
self.handle_token_result(name, result)
|
2019-05-11 17:53:37 +02:00
|
|
|
end
|
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
def self.handle_token_result(name, result)
|
2019-05-11 17:53:37 +02:00
|
|
|
data = JSON.parse(result.body)
|
2019-05-30 07:04:34 +02:00
|
|
|
|
2019-05-11 17:53:37 +02:00
|
|
|
return false if (data['error'])
|
|
|
|
|
2019-05-30 07:04:34 +02:00
|
|
|
access_token = data['access_token']
|
|
|
|
refresh_token = data['refresh_token']
|
2019-05-11 17:53:37 +02:00
|
|
|
expires_at = Time.now + data['expires_in'].seconds
|
|
|
|
refresh_at = expires_at.to_time - 2.hours
|
|
|
|
|
2019-05-19 15:56:17 +02:00
|
|
|
opts = {
|
2019-06-02 12:54:31 +02:00
|
|
|
name: name
|
2019-05-19 15:56:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Jobs.enqueue_at(refresh_at, :refresh_api_access_token, opts)
|
2019-05-11 17:53:37 +02:00
|
|
|
|
2019-06-02 12:54:31 +02:00
|
|
|
CustomWizard::Api::Authorization.set(name,
|
2019-05-30 07:04:34 +02:00
|
|
|
access_token: access_token,
|
|
|
|
refresh_token: refresh_token,
|
|
|
|
token_expires_at: expires_at,
|
|
|
|
token_refresh_at: refresh_at
|
2019-05-11 17:53:37 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|