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

147 Zeilen
4 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 :authorized,
:name,
: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
def initialize(name, data, opts = {})
unless opts[:data_only]
@name = name
end
if data = data.is_a?(String) ? ::JSON.parse(data) : data
data.each do |k, v|
self.send "#{k}=", v if self.respond_to?(k)
end
end
end
def authorized
@authorized ||= @access_token && @token_expires_at.to_datetime > Time.now
end
def self.set(name, data = {})
record = self.get(name, data_only: true)
2019-05-11 17:53:37 +02:00
data.each do |k, v|
record.send "#{k}=", v if record.respond_to?(k)
end
2019-05-11 17:53:37 +02:00
PluginStore.set("custom_wizard_api_#{name}", 'authorization', record.as_json)
self.get(name)
end
2019-05-11 17:53:37 +02:00
def self.get(name, opts = {})
data = PluginStore.get("custom_wizard_api_#{name}", 'authorization')
self.new(name, data, opts)
2019-05-11 17:53:37 +02:00
end
def self.remove(name)
PluginStore.remove("custom_wizard_api_#{name}", "authorization")
2019-05-11 17:53:37 +02:00
end
def self.get_header_authorization_string(name)
protocol = authentication_protocol(name)
raise Discourse::InvalidParameters.new(:name) unless protocol.present?
raise Discourse::InvalidParameters.new(:protocol) unless [BASIC_AUTH, OAUTH2_AUTH].include? protocol
if protocol = BASIC_AUTH
username = username(name)
raise Discourse::InvalidParameters.new(:username) unless username.present?
password = password(name)
raise Discourse::InvalidParameters.new(:password) unless password.present?
authorization_string = (username + ":" + password).chomp
"Basic #{Base64.strict_encode64(authorization_string)}"
else
# must be OAUTH2
access_token = access_token(name)
raise Discourse::InvalidParameters.new(access_token) unless access_token.present?
"Bearer #{access_token}"
end
end
def self.get_token(name)
authorization = CustomWizard::Api::Authorization.get(name)
2019-05-11 17:53:37 +02:00
body = {
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',
redirect_uri: Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
2019-05-11 17:53:37 +02:00
}
result = Excon.post(
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)
)
self.handle_token_result(name, result)
2019-05-11 17:53:37 +02:00
end
def self.refresh_token(name)
authorization = CustomWizard::Api::Authorization.get(name)
2019-05-11 17:53:37 +02:00
body = {
grant_type: 'refresh_token',
refresh_token: authorization.refresh_token
2019-05-11 17:53:37 +02:00
}
authorization_string = authorization.client_id + ':' + authorization.client_secret
2019-05-11 17:53:37 +02:00
result = Excon.post(
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)
)
self.handle_token_result(name, result)
2019-05-11 17:53:37 +02:00
end
def self.handle_token_result(name, result)
2019-05-11 17:53:37 +02:00
data = JSON.parse(result.body)
2019-05-11 17:53:37 +02:00
return false if (data['error'])
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
opts = {
name: name
}
Jobs.enqueue_at(refresh_at, :refresh_api_access_token, opts)
2019-05-11 17:53:37 +02:00
CustomWizard::Api::Authorization.set(name,
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