# frozen_string_literal: true class CustomWizard::Api::Endpoint include ActiveModel::SerializerSupport attr_accessor :id, :name, :api_name, :method, :url, :content_type, :success_codes def initialize(api_name, data = {}) @api_name = api_name data.each { |k, v| self.send "#{k}=", v if self.respond_to?(k) } end def self.set(api_name, new_data) if new_data["id"] data = self.get(api_name, new_data["id"], data_only: true) endpoint_id = new_data["id"] else data = {} endpoint_id = SecureRandom.hex(3) end new_data.each { |k, v| data[k.to_sym] = v } PluginStore.set("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}", data) self.get(api_name, endpoint_id) end def self.get(api_name, endpoint_id, opts = {}) return nil if !endpoint_id if data = PluginStore.get("custom_wizard_api_#{api_name}", "endpoint_#{endpoint_id}") if opts[:data_only] data else data[:id] = endpoint_id self.new(api_name, data) end else nil end end def self.remove(api_name) PluginStoreRow.where( "plugin_name = 'custom_wizard_api_#{api_name}' AND key LIKE 'endpoint_%'", ).destroy_all end def self.list(api_name) PluginStoreRow .where("plugin_name LIKE 'custom_wizard_api_#{api_name}' AND key LIKE 'endpoint_%'") .map do |record| api_name = record["plugin_name"].sub("custom_wizard_api_", "") data = ::JSON.parse(record["value"]) data[:id] = record["key"].split("_").last self.new(api_name, data) end end def self.request(user = Discourse.system_user, api_name, endpoint_id, body) endpoint = self.get(api_name, endpoint_id) auth_string = CustomWizard::Api::Authorization.authorization_string(api_name) content_type = endpoint.content_type headers = {} headers["Authorization"] = auth_string if auth_string headers["Content-Type"] = content_type if content_type connection = Excon.new(endpoint.url, headers: headers) params = { method: endpoint.method } if body if content_type === "application/json" body = JSON.generate(body) elsif content_type === "application/x-www-form-urlencoded" body = URI.encode_www_form(body) end params[:body] = body end response = connection.request(params) if endpoint.success_codes.include?(response.status) begin result = JSON.parse(response.body) rescue JSON::ParserError result = response.body end CustomWizard::Api::LogEntry.set(api_name, log_params(user, "SUCCESS", endpoint.url)) result else message = "API request failed" CustomWizard::Api::LogEntry.set(api_name, log_params(user, "FAIL", endpoint.url, message)) { error: message } end end def self.log_params(user, status, url, message = "") { time: Time.now, user_id: user.id, status: status, url: url, error: message } end end