mirror of
https://github.com/ditkrg/rswag.git
synced 2026-01-25 15:22:56 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8e9ab3221 | ||
|
|
26a3bf5079 | ||
|
|
12daacf9a5 | ||
|
|
05e1e2271f | ||
|
|
07ae261e54 | ||
|
|
06d00de992 | ||
|
|
ad9cd5de66 |
@@ -1 +1 @@
|
||||
2.3.0
|
||||
2.3.1
|
||||
|
||||
1
Gemfile
1
Gemfile
@@ -28,6 +28,7 @@ group :test do
|
||||
gem 'generator_spec'
|
||||
gem 'capybara'
|
||||
gem 'capybara-webkit'
|
||||
gem 'puma'
|
||||
end
|
||||
|
||||
group :assets do
|
||||
|
||||
@@ -29,28 +29,27 @@ module Rswag
|
||||
path_item_params = metadata[:path_item][:parameters] || []
|
||||
security_params = derive_security_params(metadata, swagger_doc)
|
||||
|
||||
operation_params
|
||||
.concat(path_item_params)
|
||||
.concat(security_params)
|
||||
# NOTE: Use of + instead of concat to avoid mutation of the metadata object
|
||||
(operation_params + path_item_params + security_params)
|
||||
.map { |p| p['$ref'] ? resolve_parameter(p['$ref'], swagger_doc) : p }
|
||||
.uniq { |p| p[:name] }
|
||||
.reject { |p| p[:required] == false && !example.respond_to?(p[:name]) }
|
||||
end
|
||||
|
||||
def derive_security_params(metadata, swagger_doc)
|
||||
requirements = metadata[:operation][:security] || swagger_doc[:security]
|
||||
scheme_names = requirements ? requirements.map { |r| r.keys.first } : []
|
||||
applicable_schemes = (swagger_doc[:securityDefinitions] || {}).slice(*scheme_names).values
|
||||
requirements = metadata[:operation][:security] || swagger_doc[:security] || []
|
||||
scheme_names = requirements.flat_map { |r| r.keys }
|
||||
schemes = (swagger_doc[:securityDefinitions] || {}).slice(*scheme_names).values
|
||||
|
||||
applicable_schemes.map do |scheme|
|
||||
schemes.map do |scheme|
|
||||
param = (scheme[:type] == :apiKey) ? scheme.slice(:name, :in) : { name: 'Authorization', in: :header }
|
||||
param.merge(type: :string)
|
||||
param.merge(type: :string, required: requirements.one?)
|
||||
end
|
||||
end
|
||||
|
||||
def resolve_parameter(ref, swagger_doc)
|
||||
key = ref.sub('#/parameters/', '').to_sym
|
||||
definitions = swagger_doc[:parameters]
|
||||
key = ref.sub('#/parameters/', '')
|
||||
raise "Referenced parameter '#{ref}' must be defined" unless definitions && definitions[key]
|
||||
definitions[key]
|
||||
end
|
||||
|
||||
@@ -201,6 +201,18 @@ module Rswag
|
||||
end
|
||||
end
|
||||
|
||||
context 'basic auth' do
|
||||
before do
|
||||
swagger_doc[:securityDefinitions] = { basic: { type: :basic } }
|
||||
metadata[:operation][:security] = [ basic: [] ]
|
||||
allow(example).to receive(:Authorization).and_return('Basic foobar')
|
||||
end
|
||||
|
||||
it "sets 'HTTP_AUTHORIZATION' header to example value" do
|
||||
expect(request[:headers]).to eq('HTTP_AUTHORIZATION' => 'Basic foobar')
|
||||
end
|
||||
end
|
||||
|
||||
context 'apiKey' do
|
||||
before do
|
||||
swagger_doc[:securityDefinitions] = { apiKey: { type: :apiKey, name: 'api_key', in: key_location } }
|
||||
@@ -223,17 +235,22 @@ module Rswag
|
||||
expect(request[:headers]).to eq('api_key' => 'foobar')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'basic auth' do
|
||||
before do
|
||||
swagger_doc[:securityDefinitions] = { basic: { type: :basic } }
|
||||
metadata[:operation][:security] = [ basic: [] ]
|
||||
allow(example).to receive(:Authorization).and_return('Basic foobar')
|
||||
end
|
||||
context 'in header with auth param already added' do
|
||||
let(:key_location) { :header }
|
||||
before do
|
||||
metadata[:operation][:parameters] = [
|
||||
{ name: 'q1', in: :query, type: :string },
|
||||
{ name: 'api_key', in: :header, type: :string }
|
||||
]
|
||||
allow(example).to receive(:q1).and_return('foo')
|
||||
allow(example).to receive(:api_key).and_return('foobar')
|
||||
end
|
||||
|
||||
it "sets 'HTTP_AUTHORIZATION' header to example value" do
|
||||
expect(request[:headers]).to eq('HTTP_AUTHORIZATION' => 'Basic foobar')
|
||||
it 'adds authorization parameter only once' do
|
||||
expect(request[:headers]).to eq('api_key' => 'foobar')
|
||||
expect(metadata[:operation][:parameters].size).to eq 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -249,6 +266,23 @@ module Rswag
|
||||
end
|
||||
end
|
||||
|
||||
context 'paired security requirements' do
|
||||
before do
|
||||
swagger_doc[:securityDefinitions] = {
|
||||
basic: { type: :basic },
|
||||
api_key: { type: :apiKey, name: 'api_key', in: :query }
|
||||
}
|
||||
metadata[:operation][:security] = [ { basic: [], api_key: [] } ]
|
||||
allow(example).to receive(:Authorization).and_return('Basic foobar')
|
||||
allow(example).to receive(:api_key).and_return('foobar')
|
||||
end
|
||||
|
||||
it "sets both params to example values" do
|
||||
expect(request[:headers]).to eq('HTTP_AUTHORIZATION' => 'Basic foobar')
|
||||
expect(request[:path]).to eq('/blogs?api_key=foobar')
|
||||
end
|
||||
end
|
||||
|
||||
context "path-level parameters" do
|
||||
before do
|
||||
metadata[:operation][:parameters] = [ { name: 'q1', in: :query, type: :string } ]
|
||||
@@ -264,7 +298,7 @@ module Rswag
|
||||
|
||||
context 'referenced parameters' do
|
||||
before do
|
||||
swagger_doc[:parameters] = { 'q1' => { name: 'q1', in: :query, type: :string } }
|
||||
swagger_doc[:parameters] = { q1: { name: 'q1', in: :query, type: :string } }
|
||||
metadata[:operation][:parameters] = [ { '$ref' => '#/parameters/q1' } ]
|
||||
allow(example).to receive(:q1).and_return('foo')
|
||||
end
|
||||
|
||||
@@ -2,10 +2,29 @@ class AuthTestsController < ApplicationController
|
||||
|
||||
# POST /auth-tests/basic
|
||||
def basic
|
||||
if authenticate_with_http_basic { |u, p| u == 'jsmith' && p == 'jspass' }
|
||||
head :no_content
|
||||
else
|
||||
request_http_basic_authentication
|
||||
end
|
||||
return head :unauthorized unless authenticate_basic
|
||||
head :no_content
|
||||
end
|
||||
|
||||
# POST /auth-tests/api-key
|
||||
def api_key
|
||||
return head :unauthorized unless authenticate_api_key
|
||||
head :no_content
|
||||
end
|
||||
|
||||
# POST /auth-tests/basic-and-api-key
|
||||
def basic_and_api_key
|
||||
return head :unauthorized unless authenticate_basic and authenticate_api_key
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticate_basic
|
||||
authenticate_with_http_basic { |u, p| u == 'jsmith' && p == 'jspass' }
|
||||
end
|
||||
|
||||
def authenticate_api_key
|
||||
params['api_key'] == 'foobar'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,8 @@ TestApp::Application.routes.draw do
|
||||
put '/blogs/:id/upload', to: 'blogs#upload'
|
||||
|
||||
post 'auth-tests/basic', to: 'auth_tests#basic'
|
||||
post 'auth-tests/api-key', to: 'auth_tests#api_key'
|
||||
post 'auth-tests/basic-and-api-key', to: 'auth_tests#basic_and_api_key'
|
||||
|
||||
mount Rswag::Api::Engine => 'api-docs'
|
||||
mount Rswag::Ui::Engine => 'api-docs'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# encoding: UTF-8
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
@@ -8,16 +9,16 @@
|
||||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
||||
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160218212104) do
|
||||
ActiveRecord::Schema.define(:version => 20160218212104) do
|
||||
|
||||
create_table "blogs", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.text "content"
|
||||
t.string "thumbnail"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
create_table "blogs", :force => true do |t|
|
||||
t.string "title"
|
||||
t.text "content"
|
||||
t.string "thumbnail"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ describe 'Auth Tests API', type: :request, swagger_doc: 'v1/swagger.json' do
|
||||
|
||||
path '/auth-tests/basic' do
|
||||
post 'Authenticates with basic auth' do
|
||||
tags 'Auth Test'
|
||||
tags 'Auth Tests'
|
||||
operationId 'testBasicAuth'
|
||||
security [ basic_auth: [] ]
|
||||
|
||||
@@ -19,4 +19,42 @@ describe 'Auth Tests API', type: :request, swagger_doc: 'v1/swagger.json' do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
path '/auth-tests/api-key' do
|
||||
post 'Authenticates with an api key' do
|
||||
tags 'Auth Tests'
|
||||
operationId 'testApiKey'
|
||||
security [ api_key: [] ]
|
||||
|
||||
response '204', 'Valid credentials' do
|
||||
let(:api_key) { 'foobar' }
|
||||
run_test!
|
||||
end
|
||||
|
||||
response '401', 'Invalid credentials' do
|
||||
let(:api_key) { 'barfoo' }
|
||||
run_test!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
path '/auth-tests/basic-and-api-key' do
|
||||
post 'Authenticates with basic auth and api key' do
|
||||
tags 'Auth Tests'
|
||||
operationId 'testBasicAndApiKey'
|
||||
security [ { basic_auth: [], api_key: [] } ]
|
||||
|
||||
response '204', 'Valid credentials' do
|
||||
let(:Authorization) { "Basic #{::Base64.strict_encode64('jsmith:jspass')}" }
|
||||
let(:api_key) { 'foobar' }
|
||||
run_test!
|
||||
end
|
||||
|
||||
response '401', 'Invalid credentials' do
|
||||
let(:Authorization) { "Basic #{::Base64.strict_encode64('jsmith:jspass')}" }
|
||||
let(:api_key) { 'barfoo' }
|
||||
run_test!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -91,7 +91,7 @@ describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do
|
||||
let(:id) { blog.id }
|
||||
let(:blog) { Blog.create(title: 'foo', content: 'bar') }
|
||||
|
||||
put 'upload a blog thumbnail' do
|
||||
put 'Uploads a blog thumbnail' do
|
||||
tags 'Blogs'
|
||||
description 'Upload a thumbnail for specific blog by id'
|
||||
operationId 'uploadThumbnailBlog'
|
||||
|
||||
@@ -54,10 +54,7 @@ RSpec.configure do |config|
|
||||
name: 'api_key',
|
||||
in: :query
|
||||
}
|
||||
},
|
||||
security: [
|
||||
{ api_key: [] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"post": {
|
||||
"summary": "Authenticates with basic auth",
|
||||
"tags": [
|
||||
"Auth Test"
|
||||
"Auth Tests"
|
||||
],
|
||||
"operationId": "testBasicAuth",
|
||||
"security": [
|
||||
@@ -29,6 +29,57 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth-tests/api-key": {
|
||||
"post": {
|
||||
"summary": "Authenticates with an api key",
|
||||
"tags": [
|
||||
"Auth Tests"
|
||||
],
|
||||
"operationId": "testApiKey",
|
||||
"security": [
|
||||
{
|
||||
"api_key": [
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "Valid credentials"
|
||||
},
|
||||
"401": {
|
||||
"description": "Invalid credentials"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth-tests/basic-and-api-key": {
|
||||
"post": {
|
||||
"summary": "Authenticates with basic auth and api key",
|
||||
"tags": [
|
||||
"Auth Tests"
|
||||
],
|
||||
"operationId": "testBasicAndApiKey",
|
||||
"security": [
|
||||
{
|
||||
"basic_auth": [
|
||||
|
||||
],
|
||||
"api_key": [
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "Valid credentials"
|
||||
},
|
||||
"401": {
|
||||
"description": "Invalid credentials"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/blogs": {
|
||||
"post": {
|
||||
"summary": "Creates a blog",
|
||||
@@ -149,7 +200,7 @@
|
||||
}
|
||||
],
|
||||
"put": {
|
||||
"summary": "upload a blog thumbnail",
|
||||
"summary": "Uploads a blog thumbnail",
|
||||
"tags": [
|
||||
"Blogs"
|
||||
],
|
||||
@@ -226,12 +277,5 @@
|
||||
"name": "api_key",
|
||||
"in": "query"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"api_key": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user