Merge branch 'master' into bug/2937-core-missing-modules

This commit is contained in:
shockey
2017-04-26 18:34:58 -07:00
committed by GitHub
16 changed files with 200 additions and 123 deletions

3
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,3 @@
When reporting an issue, please provide the following details:
- swagger-ui version
- a swagger file reproducing the issue

View File

@@ -75,7 +75,7 @@ To use swagger-ui's bundles, you should take a look at the [source of swagger-ui
}) })
``` ```
If you'd like to use the bundle files via npm, check out the [`swagger-ui-dist` package](npmjs.com/package/swagger-ui-dist). If you'd like to use the bundle files via npm, check out the [`swagger-ui-dist` package](https://www.npmjs.com/package/swagger-ui-dist).
#### Parameters #### Parameters
@@ -86,6 +86,7 @@ spec | A JSON object describing the OpenAPI Specification. When used, the `url`
validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation. validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger. dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
oauth2RedirectUrl | OAuth redirect URL oauth2RedirectUrl | OAuth redirect URL
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0dA;;;;;;AAoIA;AAk7FA;AAmtCA;;;;;AA0uIA;AA+4IA;AAm9FA;AA2rGA;AA8lFA;AA2nFA;AAu9CA;AAyhDA;AAqrCA;AAy4EA;AA8/GA;;;;;;;;;;;;;;AA+mJA;AA4mIA;AAquJA;AAwsHA;AAinGA;AAmiEA;AAy4DA;AAm2DA;AA0nBA;;;;;;AA4iFA;AAk0FA;;;;;AA23CA;AA2qFA;AAw2CA;AAglCA;AA0/CA;AAykFA;AA+1FA;;;;;;;;;AAk4CA;AA2zIA;AAk4DA;AAolDA","sourceRoot":""} {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0dA;AAkoJA;AAyiCA;;;;;AAskCA;AAg2IA;AAu5GA;AAg1FA;AAwpEA;AAu+CA;AAs/CA;AA6rCA;AAu5EA;AA+5HA;;;;;;;;;;;;;;AA6wGA;AAyoIA;AAiuJA;AA8kHA;AAonGA;AAukEA;AA02DA;AA+2EA;AAuxGA;;;;;;AAu8EA;AA44FA;;;;;AAi5CA;AA2qFA;AAw2CA;AA2kCA;AAm/CA;AAwwEA;AAq8FA;;;;;;;;;AA82BA;AA2zIA;AAk4DA;AAolDA;;;;;;AA6kCA;AA8iHA;AAipGA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA4QA;AAitGA","sourceRoot":""} {"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA6PA;AAyiGA","sourceRoot":""}

2
dist/swagger-ui.css vendored

File diff suppressed because one or more lines are too long

14
dist/swagger-ui.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA4wCA;AAoyHA;AAuxHA;AAy4FA;AA8rCA;AAugCA;AA+hCA;AA24BA","sourceRoot":""} {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA0xCA;AAoyHA;AAuxHA;AAy4FA;AAktCA;AAmgCA;AA0iCA;AA+3BA","sourceRoot":""}

28
snapcraft.yaml Normal file
View File

@@ -0,0 +1,28 @@
name: swagger-ui
version: master
summary: The World's Most Popular API Framework
description: |
Swagger UI is part of the Swagger project. The Swagger project allows you to
produce, visualize and consume your OWN RESTful services. No proxy or 3rd
party services required. Do it your own way.
Swagger UI is a dependency-free collection of HTML, Javascript, and CSS
assets that dynamically generate beautiful documentation and sandbox from a
Swagger-compliant API. Because Swagger UI has no dependencies, you can host
it in any server environment, or on your local machine.
grade: devel
confinement: strict
apps:
swagger-ui:
command: sh -c \"cd $SNAP/lib/node_modules/swagger-ui/dist && http-server -a localhost -p 8080\"
daemon: simple
plugs: [network, network-bind]
parts:
swagger-ui:
source: .
plugin: nodejs
npm-run: [build]
node-packages: [handlebars, http-server]

View File

@@ -26,7 +26,7 @@ export default class Oauth2 extends React.Component {
let username = auth && auth.get("username") || "" let username = auth && auth.get("username") || ""
let clientId = auth && auth.get("clientId") || "" let clientId = auth && auth.get("clientId") || ""
let clientSecret = auth && auth.get("clientSecret") || "" let clientSecret = auth && auth.get("clientSecret") || ""
let passwordType = auth && auth.get("passwordType") || "none" let passwordType = auth && auth.get("passwordType") || "basic"
this.state = { this.state = {
name: name, name: name,
@@ -108,44 +108,46 @@ export default class Oauth2 extends React.Component {
<p className="flow">Flow: <code>{ schema.get("flow") }</code></p> <p className="flow">Flow: <code>{ schema.get("flow") }</code></p>
{ {
flow === PASSWORD && ( !isAuthorized || isAuthorized && this.state.username) && <Row> flow !== PASSWORD ? null
<Col tablet={2} desktop={2}>username:</Col> : <Row>
<Col tablet={10} desktop={10}> <Row>
<label htmlFor="oauth_username">username:</label>
{ {
isAuthorized ? <span>{ this.state.username }</span> isAuthorized ? <code> { this.state.username } </code>
: <input type="text" data-name="username" onChange={ this.onInputChange }/> : <Col tablet={10} desktop={10}>
} <input id="oauth_username" type="text" data-name="username" onChange={ this.onInputChange }/>
</Col> </Col>
</Row>
} }
</Row>
{ {
flow === PASSWORD && !isAuthorized && <Row>
<Col tablet={2} desktop={2}>password:</Col> }
<Col tablet={10} desktop={10}> <Row>
<input type="password" data-name="password" onChange={ this.onInputChange }/> <label htmlFor="oauth_password">password:</label>
{
isAuthorized ? <code> ****** </code>
: <Col tablet={10} desktop={10}>
<input id="oauth_password" type="password" data-name="password" onChange={ this.onInputChange }/>
</Col> </Col>
</Row>
} }
</Row>
<Row>
<label htmlFor="password_type">type:</label>
{ {
flow === PASSWORD && <Row> isAuthorized ? <code> { this.state.passwordType } </code>
<Col tablet={2} desktop={2}>type:</Col> : <Col tablet={10} desktop={10}>
<Col tablet={10} desktop={10}> <select id="password_type" data-name="passwordType" onChange={ this.onInputChange }>
{
isAuthorized ? <span>{ this.state.passwordType }</span>
: <select data-name="passwordType" onChange={ this.onInputChange }>
<option value="none">None or other</option>
<option value="basic">Basic auth</option> <option value="basic">Basic auth</option>
<option value="request">Request body</option> <option value="request-body">Request body</option>
<option value="query">Query parameters</option>
</select> </select>
}
</Col> </Col>
}
</Row>
</Row> </Row>
} }
{ {
( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "none") ) && ( flow === APPLICATION || flow === IMPLICIT || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) &&
( !isAuthorized || isAuthorized && this.state.clientId) && <Row> ( !isAuthorized || isAuthorized && this.state.clientId) && <Row>
<label htmlFor="client_id">client_id:</label> <label htmlFor="client_id">client_id:</label>
{ {
@@ -159,7 +161,7 @@ export default class Oauth2 extends React.Component {
} }
{ {
( flow === APPLICATION || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "none") ) && <Row> ( flow === APPLICATION || flow === ACCESS_CODE || ( flow === PASSWORD && this.state.passwordType!== "basic") ) && <Row>
<label htmlFor="client_secret">client_secret:</label> <label htmlFor="client_secret">client_secret:</label>
{ {
isAuthorized ? <code> ****** </code> isAuthorized ? <code> ****** </code>

View File

@@ -16,7 +16,7 @@ export default function authorize ( auth, authActions, errActions, configs ) {
} }
if (flow === "application") { if (flow === "application") {
authActions.authorizeOauth2Application(auth) authActions.authorizeApplication(auth)
return return
} }

View File

@@ -1,5 +1,5 @@
import win from "core/window" import win from "core/window"
import { btoa } from "core/utils" import { btoa, buildFormData } from "core/utils"
export const SHOW_AUTH_POPUP = "show_popup" export const SHOW_AUTH_POPUP = "show_popup"
export const AUTHORIZE = "authorize" export const AUTHORIZE = "authorize"
@@ -70,25 +70,33 @@ export function authorizeOauth2(payload) {
export const authorizePassword = ( auth ) => ( { fn, authActions, errActions } ) => { export const authorizePassword = ( auth ) => ( { fn, authActions, errActions } ) => {
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
let credentials = {
grant_type: "password",
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
}
let req = { let req = {
url: schema.get("tokenUrl"), url: schema.get("tokenUrl"),
method: "post", method: "post",
headers: { headers: {
"content-type": "application/x-www-form-urlencoded" "Content-Type": "application/x-www-form-urlencoded"
}, },
query: { query: {}
grant_type: "password",
username,
password,
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
}
} }
if ( passwordType === "basic") { if ( passwordType === "basic") {
req.headers.authorization = "Basic " + btoa(clientId + ":" + clientSecret) req.headers.Authorization = "Basic " + btoa(username + ":" + password)
} else if ( passwordType === "request") { } else {
req.query = Object.assign(req.query, { client_id: clientId, client_secret: clientSecret }) credentials = Object.assign({}, credentials, {username} , {password})
if ( passwordType === "query") {
if ( clientId ) { req.query.client_id = clientId }
if ( clientSecret ) { req.query.client_secret = clientSecret }
} else {
credentials = Object.assign({}, credentials, {client_id: clientId}, {client_secret: clientSecret})
} }
}
req.body = buildFormData(credentials)
return fn.fetch(req) return fn.fetch(req)
.then(( response ) => { .then(( response ) => {
let token = JSON.parse(response.data) let token = JSON.parse(response.data)
@@ -120,20 +128,30 @@ export const authorizePassword = ( auth ) => ( { fn, authActions, errActions } )
.catch(err => { errActions.newAuthErr( err ) }) .catch(err => { errActions.newAuthErr( err ) })
} }
export const authorizeOauth2Application = ( auth ) => ( { fn, authActions, errActions } ) => { export const authorizeApplication = ( auth ) => ( { fn, authActions, errActions } ) => {
let { schema, scopes, name, clientId, clientSecret } = auth let { schema, scopes, name, clientId, clientSecret } = auth
let credentials = {
grant_type: "client_credentials",
client_id: clientId,
client_secret: clientSecret,
scope: scopes.join(scopeSeparator)
}
fn.fetch(schema.get("tokenUrl"), {
method: "post", headers: { return fn.fetch({
url: schema.get("tokenUrl"),
method: "post",
headers: {
"Accept":"application/json, text/plain, */*", "Accept":"application/json, text/plain, */*",
"Content-Type": "application/x-www-form-urlencoded" "Content-Type": "application/x-www-form-urlencoded"
}, },
body: "grant_type=client_credentials" + body: buildFormData(credentials)
"&client_id=" + encodeURIComponent(clientId) +
"&client_secret=" + encodeURIComponent(clientSecret) +
"&scope=" + encodeURIComponent(scopes.join(scopeSeparator))
}) })
.then(function (response) { .then(function (response) {
let token = JSON.parse(response.data)
let error = token && ( token.error || "" )
let parseError = token && ( token.parseError || "" )
if ( !response.ok ) { if ( !response.ok ) {
errActions.newAuthErr( { errActions.newAuthErr( {
authId: name, authId: name,
@@ -142,12 +160,19 @@ export const authorizeOauth2Application = ( auth ) => ( { fn, authActions, errAc
message: response.statusText message: response.statusText
} ) } )
return return
} else {
response.json()
.then(function (json){
authActions.authorizeOauth2({ auth, token: json})
})
} }
if ( error || parseError ) {
errActions.newAuthErr({
authId: name,
level: "error",
source: "auth",
message: JSON.stringify(token)
})
return
}
authActions.authorizeOauth2({ auth, token })
}) })
.catch(err => { errActions.newAuthErr( err ) }) .catch(err => { errActions.newAuthErr( err ) })
} }

View File

@@ -566,3 +566,15 @@ export const sorters = {
method: (a, b) => a.get("method").localeCompare(b.get("method")) method: (a, b) => a.get("method").localeCompare(b.get("method"))
} }
} }
export const buildFormData = (data) => {
let formArr = []
for (let name in data) {
let val = data[name]
if (val !== undefined && val !== "") {
formArr.push([name, "=", encodeURIComponent(val).replace(/%20/g,"+")].join(""))
}
}
return formArr.join("&")
}

View File

@@ -502,6 +502,11 @@ body
{ {
color: #fff !important; color: #fff !important;
} }
.headerline
{
display: block;
}
} }
.scheme-container .scheme-container

View File

@@ -1,3 +1,3 @@
This directory is used to build the `swagger-ui-dist` npm package. This module, `swagger-ui-dist`, exposes Swagger-UI's entire dist folder as a dependency-free npm module.
For anything else, check the [Swagger-UI](https://github.com/swagger-api/swagger-ui) repository. Use `swagger-ui` instead, if you'd like to have npm install dependencies for you.