1
0
Fork 0

Improve flexibility and structure of send_to_api action

Dieser Commit ist enthalten in:
Angus McLeod 2019-08-13 14:11:46 +10:00
Ursprung 6ad821024a
Commit 30390e8264
10 geänderte Dateien mit 92 neuen und 56 gelöschten Zeilen

Datei anzeigen

@ -11,6 +11,8 @@ export default Ember.Controller.extend({
showRemove: Ember.computed.not('isNew'),
showRedirectUri: Ember.computed.and('threeLeggedOauth', 'api.name'),
responseIcon: null,
contentTypes: ['application/json', 'application/x-www-form-urlencoded'],
successCodes: [100, 101, 102, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 303, 304, 305, 306, 307, 308],
@computed('saveDisabled', 'api.authType', 'api.authUrl', 'api.tokenUrl', 'api.clientId', 'api.clientSecret', 'threeLeggedOauth')
authDisabled(saveDisabled, authType, authUrl, tokenUrl, clientId, clientSecret, threeLeggedOauth) {
@ -24,7 +26,7 @@ export default Ember.Controller.extend({
return !name || !authType;
},
authorizationTypes: ['basic', 'oauth_2', 'oauth_3'],
authorizationTypes: ['none', 'basic', 'oauth_2', 'oauth_3'],
isBasicAuth: Ember.computed.equal('api.authType', 'basic'),
@computed('api.authType')
@ -124,13 +126,15 @@ export default Ember.Controller.extend({
requiredParams = ['authUrl', 'tokenUrl', 'clientId', 'clientSecret'];
}
for (let rp of requiredParams) {
if (!api[rp]) {
let key = rp.replace('auth', '');
error = `${I18n.t(`admin.wizard.api.auth.${key.underscore()}`)} is required for ${authType}`;
break;
if (requiredParams) {
for (let rp of requiredParams) {
if (!api[rp]) {
let key = rp.replace('auth', '');
error = `${I18n.t(`admin.wizard.api.auth.${key.underscore()}`)} is required for ${authType}`;
break;
}
data[rp.underscore()] = api[rp];
}
data[rp.underscore()] = api[rp];
}
const params = api.authParams;

Datei anzeigen

@ -228,18 +228,28 @@
<li>
<div class="endpoint">
<div class="endpoint-">
{{input value=endpoint.name
placeholder=(i18n 'admin.wizard.api.endpoint.name')}}
{{combo-box content=endpointMethods
value=endpoint.method
none="admin.wizard.api.endpoint.method"}}
{{input value=endpoint.url
placeholder=(i18n 'admin.wizard.api.endpoint.url')
class='endpoint-url'}}
{{d-button action=(action "removeEndpoint")
actionParam=endpoint
icon='times'
class='remove-endpoint'}}
<div class="top">
{{input value=endpoint.name
placeholder=(i18n 'admin.wizard.api.endpoint.name')}}
{{input value=endpoint.url
placeholder=(i18n 'admin.wizard.api.endpoint.url')
class='endpoint-url'}}
{{d-button action=(action "removeEndpoint")
actionParam=endpoint
icon='times'
class='remove-endpoint'}}
</div>
<div class="bottom">
{{combo-box content=endpointMethods
value=endpoint.method
none="admin.wizard.api.endpoint.method"}}
{{combo-box content=contentTypes
value=endpoint.content_type
none="admin.wizard.api.endpoint.content_type"}}
{{multi-select content=successCodes
values=endpoint.success_codes
none="admin.wizard.api.endpoint.success_codes"}}
</div>
</div>
</div>
</li>

Datei anzeigen

@ -446,14 +446,19 @@
}
.endpoint {
display: flex;
margin-top: 20px;
.top, .bottom {
display: flex;
}
.top {
margin-bottom: 15px;
}
.combo-box {
width: 200px;
margin-right: 10px;
margin-top: -2px;
width: 150px;
width: 210px;
}
input {
@ -462,7 +467,7 @@
}
.endpoint-url {
width: 300px;
flex: 1 1 auto;
}
.remove-endpoint {

Datei anzeigen

@ -211,6 +211,8 @@ en:
name: "Endpoint name"
method: "Select a method"
url: "Enter a url"
content_type: "Select a content type"
success_codes: "Select success codes"
log:
label: "Logs"

Datei anzeigen

@ -64,7 +64,7 @@ class CustomWizard::Api::Authorization
PluginStore.remove("custom_wizard_api_#{api_name}", "authorization")
end
def self.get_header_authorization_string(name)
def self.authorization_string(name)
auth = CustomWizard::Api::Authorization.get(name)
raise Discourse::InvalidParameters.new(:name) unless auth.present?
@ -72,9 +72,11 @@ class CustomWizard::Api::Authorization
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)}"
else
elsif ['oauth_3', 'oauth_2'].include?(auth.auth_type)
raise Discourse::InvalidParameters.new(auth.access_token) unless auth.access_token.present?
"Bearer #{auth.access_token}"
else
nil
end
end

Datei anzeigen

@ -5,7 +5,9 @@ class CustomWizard::Api::Endpoint
:name,
:api_name,
:method,
:url
:url,
:content_type,
:success_codes
def initialize(api_name, data={})
@api_name = api_name
@ -62,40 +64,49 @@ class CustomWizard::Api::Endpoint
end
end
def self.request(user, api_name, endpoint_id, body)
def self.request(user = Discourse.system_user, api_name, endpoint_id, body)
endpoint = self.get(api_name, endpoint_id)
auth = CustomWizard::Api::Authorization.get_header_authorization_string(api_name)
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(
URI.parse(URI.encode(endpoint.url)).to_s,
:headers => {
"Authorization" => auth,
"Accept" => "application/json, */*",
"Content-Type" => "application/json"
}
)
connection = Excon.new(URI.parse(URI.encode(endpoint.url)).to_s, headers: headers)
params = {
method: endpoint.method
}
params = { method: endpoint.method }
if body
body = JSON.generate(body)
body.delete! '\\'
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
begin
response = connection.request(params)
log_params = {time: Time.now, user_id: user.id, status: 'SUCCESS', url: endpoint.url, error: ""}
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)
return JSON.parse(response.body)
rescue
# TODO: improve error detail
log_params = {time: Time.now, user_id: user.id, status: 'FAILURE', url: endpoint.url, error: "API request failed"}
CustomWizard::Api::LogEntry.set(api_name, log_params)
return JSON.parse "[{\"error\":\"API request failed\"}]"
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

Datei anzeigen

@ -492,7 +492,7 @@ class CustomWizard::Builder
rescue JSON::ParserError
raise Discourse::InvalidParameters, "Invalid API body definition: #{action['api_body']} for #{action['title']}"
end
api_body = CustomWizard::Builder.fill_placeholders(JSON.generate(api_body_parsed), user, data)
api_body = JSON.parse(CustomWizard::Builder.fill_placeholders(JSON.generate(api_body_parsed), user, data))
end
result = CustomWizard::Api::Endpoint.request(user, action['api'], action['api_endpoint'], api_body)

Datei anzeigen

@ -101,7 +101,7 @@ after_initialize do
load File.expand_path('../lib/api/api.rb', __FILE__)
load File.expand_path('../lib/api/authorization.rb', __FILE__)
load File.expand_path('../lib/api/endpoint.rb', __FILE__)
load File.expand_path('../lib/api/logentry.rb', __FILE__)
load File.expand_path('../lib/api/log_entry.rb', __FILE__)
load File.expand_path('../controllers/api.rb', __FILE__)
load File.expand_path('../serializers/api/api_serializer.rb', __FILE__)
load File.expand_path('../serializers/api/authorization_serializer.rb', __FILE__)

Datei anzeigen

@ -2,7 +2,9 @@ class CustomWizard::Api::EndpointSerializer < ApplicationSerializer
attributes :id,
:name,
:method,
:url
:url,
:content_type,
:success_codes
def method
object.send('method')