Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-24 10:20:28 +01:00
157 Zeilen
4,3 KiB
Ruby
157 Zeilen
4,3 KiB
Ruby
# frozen_string_literal: true
|
|
require "excon"
|
|
|
|
class CustomWizard::Api::Authorization
|
|
include ActiveModel::SerializerSupport
|
|
|
|
attr_accessor :api_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(api_name, data = {})
|
|
@api_name = api_name
|
|
|
|
data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) }
|
|
end
|
|
|
|
def authorized
|
|
@authorized ||= @access_token && @token_expires_at.to_datetime > Time.now
|
|
end
|
|
|
|
def self.set(api_name, new_data = {})
|
|
api_name = api_name.underscore
|
|
|
|
data = self.get(api_name, data_only: true) || {}
|
|
|
|
new_data.each { |k, v| data[k.to_sym] = v }
|
|
|
|
PluginStore.set("custom_wizard_api_#{api_name}", "authorization", data)
|
|
|
|
self.get(api_name)
|
|
end
|
|
|
|
def self.get(api_name, opts = {})
|
|
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
|
|
end
|
|
|
|
def self.remove(api_name)
|
|
PluginStore.remove("custom_wizard_api_#{api_name}", "authorization")
|
|
end
|
|
|
|
def self.authorization_string(name)
|
|
auth = CustomWizard::Api::Authorization.get(name)
|
|
raise Discourse::InvalidParameters.new(:name) if auth.blank?
|
|
|
|
if auth.auth_type === "basic"
|
|
raise Discourse::InvalidParameters.new(:username) if auth.username.blank?
|
|
raise Discourse::InvalidParameters.new(:password) if auth.password.blank?
|
|
"Basic #{Base64.strict_encode64((auth.username + ":" + auth.password).chomp)}"
|
|
elsif %w[oauth_3 oauth_2].include?(auth.auth_type)
|
|
raise Discourse::InvalidParameters.new(auth.access_token) if auth.access_token.blank?
|
|
"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 = {}
|
|
|
|
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
|
|
|
|
if type === "oauth_3"
|
|
body["code"] = authorization.code
|
|
body["redirect_uri"] = Discourse.base_url + "/admin/wizards/apis/#{name}/redirect"
|
|
end
|
|
|
|
connection =
|
|
Excon.new(
|
|
authorization.token_url,
|
|
headers: {
|
|
"Content-Type" => "application/x-www-form-urlencoded",
|
|
},
|
|
method: "GET",
|
|
query: URI.encode_www_form(body),
|
|
)
|
|
begin
|
|
result = connection.request()
|
|
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
|
|
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)
|
|
end
|
|
|
|
def self.handle_token_result(name, result)
|
|
result_data = JSON.parse(result.body)
|
|
|
|
return result_data if result_data["error"]
|
|
|
|
data = {}
|
|
|
|
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
|
|
|
|
opts = { name: name }
|
|
|
|
Jobs.enqueue_at(data["token_refresh_at"], :refresh_api_access_token, opts)
|
|
end
|
|
|
|
CustomWizard::Api::Authorization.set(name, data)
|
|
end
|
|
end
|