Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-09 20:02:54 +01:00
Improve flexibility and structure of send_to_api action
Dieser Commit ist enthalten in:
Ursprung
6ad821024a
Commit
30390e8264
10 geänderte Dateien mit 92 neuen und 56 gelöschten Zeilen
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -2,7 +2,9 @@ class CustomWizard::Api::EndpointSerializer < ApplicationSerializer
|
|||
attributes :id,
|
||||
:name,
|
||||
:method,
|
||||
:url
|
||||
:url,
|
||||
:content_type,
|
||||
:success_codes
|
||||
|
||||
def method
|
||||
object.send('method')
|
||||
|
|
Laden …
In neuem Issue referenzieren