-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose error responses in the spec output #25
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,5 +11,6 @@ gem "rspec", "~> 3.0" | |
gem "rubocop", "~> 1.21" | ||
|
||
group :test do | ||
gem "pry" | ||
gem "simplecov", require: false | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# frozen_string_literal: true | ||
|
||
module CoreAPI | ||
module Authenticators | ||
class MainAuthenticator < Apia::Authenticator | ||
|
||
BEARER_TOKEN = "example" | ||
|
||
type :bearer | ||
|
||
potential_error "InvalidToken" do | ||
code :invalid_token | ||
description "The token provided is invalid. In this example, you should provide '#{BEARER_TOKEN}'." | ||
http_status 403 | ||
|
||
field :given_token, type: :string | ||
end | ||
|
||
potential_error "UnauthorizedNetworkForAPIToken" do | ||
code :unauthorized_network_for_api_token | ||
description "Network is not allowed to access the API with this API token" | ||
http_status 403 | ||
|
||
field :ip_address, :string do | ||
description "The IP address the request was received from" | ||
end | ||
end | ||
|
||
def call | ||
configure_cors_response | ||
return if request.options? | ||
|
||
given_token = request.headers["authorization"]&.sub(/\ABearer /, "") | ||
if given_token == BEARER_TOKEN | ||
request.identity = { name: "Example User", id: 1234 } | ||
else | ||
raise_error "CoreAPI/MainAuthenticator/InvalidToken", given_token: given_token.to_s | ||
end | ||
end | ||
|
||
private | ||
|
||
# These are not strictly required, but it allows the app to work with swagger-ui. | ||
def configure_cors_response | ||
# Define a list of cors methods that are permitted for the request. | ||
cors.methods = %w[GET POST PUT PATCH DELETE OPTIONS] | ||
|
||
# Define a list of cors headers that are permitted for the request. | ||
cors.headers = %w[Authorization Content-Type] # or allow all with '*' | ||
|
||
# Define a the hostname to allow for CORS requests. | ||
cors.origin = "*" # or 'example.com' | ||
end | ||
|
||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
require "core_api/errors/rate_limit_reached" | ||
|
||
module CoreAPI | ||
module Authenticators | ||
class TimeControllerAuthenticator < Apia::Authenticator | ||
|
||
potential_error CoreAPI::Errors::RateLimitReached | ||
|
||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
require "core_api/errors/rate_limit_reached" | ||
|
||
module CoreAPI | ||
module Authenticators | ||
class TimeNowAuthenticator < Apia::Authenticator | ||
|
||
potential_error "WrongDayOfWeek" do | ||
code :wrong_day_of_week | ||
description "You called this API on the wrong day of the week, try again tomorrow" | ||
http_status 503 | ||
end | ||
|
||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
module CoreAPI | ||
module Errors | ||
class RateLimitReached < Apia::Error | ||
|
||
code :rate_limit_reached | ||
http_status 429 | ||
description "You have reached the rate limit for this type of request" | ||
|
||
field :total_permitted, type: :integer do | ||
description "The total number of requests per minute that are permitted" | ||
end | ||
|
||
end | ||
end | ||
end |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ module Helpers | |
# A component schema is a re-usable schema that can be referenced by other parts of the spec | ||
# e.g. { "$ref": "#/components/schemas/PaginationObject" } | ||
def add_to_components_schemas(definition, id, **schema_opts) | ||
return unless @spec.dig(:components, :schemas, id).nil? | ||
return true unless @spec.dig(:components, :schemas, id).nil? | ||
|
||
component_schema = {} | ||
@spec[:components][:schemas][id] = component_schema | ||
|
@@ -19,6 +19,11 @@ def add_to_components_schemas(definition, id, **schema_opts) | |
id: id, | ||
**schema_opts | ||
).add_to_spec | ||
|
||
return true if component_schema.present? | ||
|
||
@spec[:components][:schemas].delete(id) | ||
false | ||
Comment on lines
+22
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the schema is blank, then we don't need a $ref for it. This can happen with potential errors when they have no additional fields and thus the |
||
end | ||
|
||
def convert_type_to_open_api_data_type(type) | ||
|
@@ -35,13 +40,18 @@ def convert_type_to_open_api_data_type(type) | |
|
||
def generate_schema_ref(definition, id: nil, **schema_opts) | ||
id ||= generate_id_from_definition(definition.type.klass.definition) | ||
add_to_components_schemas(definition, id, **schema_opts) | ||
{ "$ref": "#/components/schemas/#{id}" } | ||
success = add_to_components_schemas(definition, id, **schema_opts) | ||
|
||
if success | ||
{ "$ref": "#/components/schemas/#{id}" } | ||
else # no properties were defined, so just declare an object with unknown properties | ||
{ type: "object" } | ||
end | ||
end | ||
|
||
# forward slashes do not work in ids (e.g. schema ids) | ||
def generate_id_from_definition(definition) | ||
definition.id.gsub(/\//, "_") | ||
definition.id.gsub(/\//, "") | ||
Comment on lines
-44
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I decided to get rid of the underscores from our ids that we use for component schemas. I thought it looked odd to have camelcase and underscores together. There is no strict format required for these in the spec, but this follows the naming pattern used in the examples. |
||
end | ||
|
||
def formatted_description(description) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# frozen_string_literal: true | ||
|
||
Dir.glob(File.join(File.dirname(__FILE__), "objects", "*.rb")).each do |file| | ||
Dir.glob(File.join(File.dirname(__FILE__), "objects", "*.rb")).sort.each do |file| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make rubocop happy |
||
require_relative file | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file is the same as before, i just decided to create an
/authenticators
directory and move it there, seeing as i wanted to add some more.