1
0
Fork 0
discourse-custom-wizard-unl.../lib/custom_wizard/api/authorization.rb

154 Zeilen
4,3 KiB
Ruby

2019-05-11 17:53:37 +02:00
require 'excon'
2019-05-31 09:54:11 +02:00
class CustomWizard::Api::Authorization
include ActiveModel::SerializerSupport
attr_accessor :api_name,
:authorized,
: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
2021-02-24 08:50:42 +01:00
def initialize(api_name, data = {})
@api_name = api_name
data.each do |k, v|
self.send "#{k}=", v if self.respond_to?(k)
end
end
def authorized
@authorized ||= @access_token && @token_expires_at.to_datetime > Time.now
end
def self.set(api_name, new_data = {})
2019-06-03 09:09:24 +02:00
api_name = api_name.underscore
data = self.get(api_name, data_only: true) || {}
2019-05-11 17:53:37 +02:00
new_data.each do |k, v|
data[k.to_sym] = v
end
2019-05-11 17:53:37 +02:00
PluginStore.set("custom_wizard_api_#{api_name}", 'authorization', data)
self.get(api_name)
end
2019-05-11 17:53:37 +02:00
def self.get(api_name, opts = {})
2019-06-03 09:09:24 +02:00
api_name = api_name.underscore
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
def self.remove(api_name)
PluginStore.remove("custom_wizard_api_#{api_name}", "authorization")
2019-05-11 17:53:37 +02:00
end
def self.authorization_string(name)
2019-06-03 09:09:24 +02:00
auth = CustomWizard::Api::Authorization.get(name)
raise Discourse::InvalidParameters.new(:name) unless auth.present?
if auth.auth_type === "basic"
raise Discourse::InvalidParameters.new(:username) unless auth.username.present?
raise Discourse::InvalidParameters.new(:password) unless auth.password.present?
"Basic #{Base64.strict_encode64((auth.username + ":" + auth.password).chomp)}"
elsif ['oauth_3', 'oauth_2'].include?(auth.auth_type)
2019-06-03 09:09:24 +02:00
raise Discourse::InvalidParameters.new(auth.access_token) unless auth.access_token.present?
"Bearer #{auth.access_token}"
else
nil
end
end
def self.get_token(name, opts = {})
authorization = CustomWizard::Api::Authorization.get(name)
type = authorization.auth_type
body = {}
2019-05-11 17:53:37 +02:00
if opts[:refresh] && type === 'oauth_3'
body['grant_type'] = 'refresh_token'
elsif type === 'oauth_2'
body['grant_type'] = 'client_credentials'
elsif type === 'oauth_3'
body['grant_type'] = 'authorization_code'
end
unless opts[:refresh]
body['client_id'] = authorization.client_id
body['client_secret'] = authorization.client_secret
end
2019-05-11 17:53:37 +02:00
if type === 'oauth_3'
body['code'] = authorization.code
body['redirect_uri'] = Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
end
2019-05-11 17:53:37 +02:00
connection = Excon.new(
authorization.token_url,
2021-02-24 08:50:42 +01:00
headers: {
"Content-Type" => "application/x-www-form-urlencoded"
2019-05-11 17:53:37 +02:00
},
2021-02-24 08:50:42 +01:00
method: 'GET',
query: URI.encode_www_form(body)
2019-05-11 17:53:37 +02:00
)
begin
result = connection.request()
2021-02-24 08:50:42 +01:00
log_params = { time: Time.now, user_id: 0, status: 'SUCCESS', url: authorization.token_url, error: "" }
CustomWizard::Api::LogEntry.set(name, log_params)
rescue SystemCallError => e
2021-02-24 08:50:42 +01:00
log_params = { time: Time.now, user_id: 0, status: 'FAILURE', url: authorization.token_url, error: "Token refresh request failed: #{e.inspect}" }
CustomWizard::Api::LogEntry.set(name, log_params)
end
self.handle_token_result(name, result)
2019-05-11 17:53:37 +02:00
end
def self.handle_token_result(name, result)
result_data = JSON.parse(result.body)
if result_data['error']
return result_data
end
2019-05-11 17:53:37 +02:00
data = {}
2019-05-11 17:53:37 +02:00
data['access_token'] = result_data['access_token']
data['refresh_token'] = result_data['refresh_token'] if result_data['refresh_token']
data['token_type'] = result_data['token_type'] if result_data['token_type']
if result_data['expires_in']
data['token_expires_at'] = Time.now + result_data['expires_in'].seconds
data['token_refresh_at'] = data['token_expires_at'].to_time - 10.minutes
2019-05-11 17:53:37 +02:00
opts = {
name: name
}
Jobs.enqueue_at(data['token_refresh_at'], :refresh_api_access_token, opts)
end
CustomWizard::Api::Authorization.set(name, data)
2019-05-11 17:53:37 +02:00
end
end