Skip to content

Commit

Permalink
feat: first support of security schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
albanm committed Oct 23, 2018
1 parent 1af3565 commit 9c5000a
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 40 deletions.
1 change: 0 additions & 1 deletion src/MultipartForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export default {
Object.keys(this.properties)
.filter(key => this.model[key] !== null)
.forEach(key => {
console.log('APPEND', key, this.model[key])
form.append(key, this.model[key])
})
return form
Expand Down
82 changes: 57 additions & 25 deletions src/OpenApi.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
<h3 class="md-subheading" style="margin: 0">{{selectedEntry.method.toUpperCase()}} {{ (api.servers && api.servers.length ? api.servers[0].url : '') + selectedEntry.path}}</h3>
<md-tabs md-right class="md-transparent">
<md-tab md-label="Documentation">
<h4 v-if="selectedEntry.security && selectedEntry.security.length">Sécurité</h4>
<security-table :selectedEntry="selectedEntry" />
<h4 v-if="(selectedEntry.parameters && selectedEntry.parameters.length) || selectedEntry.requestBody">Parameters</h4>
<parameters-table :selectedEntry="selectedEntry" :openSchemaDialog="openSchemaDialog" :openExamplesDialog="openExamplesDialog" />
<h4>Responses</h4>
Expand Down Expand Up @@ -151,36 +153,14 @@
</div>
</template>

<style lang="css">
.openapi {
position:relative;
overflow-x:hidden;
height:100%;
}
.openapi #request-form {
padding: 16px;
}
.openapi .md-table .md-table-cell.md-has-action .md-table-cell-container {
display: inherit;
}
.schema-dialog .md-dialog, .examples-dialog .md-dialog{
min-width: 800px;
}
.openapi .entry-description {
margin: 0;
}
</style>

<script>
import Vue from 'vue'
import marked from 'marked'
import RequestForm from './RequestForm.vue'
import ResponseDisplay from './ResponseDisplay.vue'
import ResponsesTable from './ResponsesTable.vue'
import SecurityTable from './SecurityTable.vue'
import ParametersTable from './ParametersTable.vue'
import SchemaView from './SchemaView.vue'
import VueMaterial from 'vue-material'
Expand All @@ -195,6 +175,7 @@ export default {
RequestForm,
ResponseDisplay,
ResponsesTable,
SecurityTable,
ParametersTable,
SchemaView
},
Expand All @@ -207,7 +188,8 @@ export default {
currentRequest: {
contentType: '',
body: '',
params: {}
params: {},
security: {}
},
currentResponse: null,
tags: {}
Expand Down Expand Up @@ -257,6 +239,13 @@ export default {
}
})
this.currentRequest.params = newParams
const newSecurity = {}
entry.security.forEach(s => {
this.$set(newSecurity, s.scheme.name, this.currentRequest.security[s.scheme.name] || null)
})
this.currentRequest.security = newSecurity
if (entry.requestBody) {
this.currentRequest.contentType = entry.requestBody.selectedType
const example = entry.requestBody.content[this.currentRequest.contentType].example
Expand Down Expand Up @@ -285,7 +274,6 @@ export default {
if (this.selectedEntry.requestBody && this.selectedEntry.requestBody.selectedType === 'multipart/form-data') {
formData = this.$refs.requestForm.getFormData()
}
console.log('formData', formData)
fetch(this.currentRequest, this.selectedEntry, this.api, formData).then(res => {
this.currentResponse = res
}, res => {
Expand Down Expand Up @@ -314,6 +302,17 @@ function fetch(request, entry, api, formData) {
[p.name]: p.schema.type === 'array' ? request.params[p.name].join(',') : request.params[p.name]
}))
)
entry.security
.filter(s => !!request.security[s.scheme.name])
.forEach(s => {
if (s.scheme.in === 'header') {
headers[s.scheme.name] = request.security[s.scheme.name]
} else if (s.scheme.in === 'query') {
params[s.scheme.name] = request.security[s.scheme.name]
}
})
const httpRequest = {
method: entry.method,
url: api.servers.length && (api.servers[0].url + entry.path.replace(/{(\w*)}/g, (m, key) => {
Expand Down Expand Up @@ -373,6 +372,7 @@ async function getTags(api) {
tags[tag].push(entry)
})
// Add path level parameters to the operation
entry.parameters = entry.parameters || []
if (derefAPI.paths[path].parameters) {
entry.parameters = derefAPI.paths[path].parameters.concat(entry.parameters)
Expand All @@ -392,6 +392,14 @@ async function getTags(api) {
}
}
// security comes from the root ofthe API or the operation
entry.security = entry.security || derefAPI.security || []
entry.security.forEach(s => {
const key = Object.keys(s)[0]
s.key = key
s.scheme = derefAPI.components.securitySchemes[key]
})
// Some preprocessing with responses
entry.responses = entry.responses || {}
Object.values(entry.responses).forEach(response => {
Expand All @@ -407,3 +415,27 @@ async function getTags(api) {
}
</script>

<style lang="css">
.openapi {
position:relative;
overflow-x:hidden;
height:100%;
}
.openapi #request-form {
padding: 16px;
}
.openapi .md-table .md-table-cell.md-has-action .md-table-cell-container {
display: inherit;
}
.schema-dialog .md-dialog, .examples-dialog .md-dialog{
min-width: 800px;
}
.openapi .entry-description {
margin: 0;
}
</style>
10 changes: 10 additions & 0 deletions src/RequestForm.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<template lang="html">
<form novalidate @submit.stop.prevent="submit" v-if="selectedEntry" id="request-form">
<md-subheader v-if="selectedEntry.security && selectedEntry.security.filter(s => s.scheme.in !== 'cookie').length">
Sécurité
</md-subheader>
<div v-for="(security, i) in selectedEntry.security.filter(s => s.scheme.in !== 'cookie')" :key="i">
<md-input-container>
<label>{{security.scheme.name}}</label>
<md-input v-model="currentRequest.security[security.scheme.name]" type="string"></md-input>
</md-input-container>
</div>

<md-subheader v-if="selectedEntry.parameters && selectedEntry.parameters.length">
Parameters
</md-subheader>
Expand Down
28 changes: 28 additions & 0 deletions src/SecurityTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template lang="html">
<md-table>
<md-table-header>
<md-table-row>
<md-table-head>Name</md-table-head>
<md-table-head>Type</md-table-head>
<md-table-head>Location</md-table-head>
</md-table-row>
</md-table-header>

<md-table-body>
<md-table-row v-for="(security, i) in selectedEntry.security" :key="i">
<md-table-cell>{{security.scheme.name}}</md-table-cell>
<md-table-cell>{{security.scheme.type}}</md-table-cell>
<md-table-cell>{{security.scheme.in}}</md-table-cell>
</md-table-row>
</md-table-body>
</md-table>
</template>

<script>
export default {
props: [ 'selectedEntry' ]
}
</script>

<style lang="css">
</style>
29 changes: 15 additions & 14 deletions test/multipart.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,27 @@
"servers": [{
"url": "http://localhost:5600/api/v1/datasets"
}],
"components": {
"securitySchemes": {
"apiKey": {
"type": "apiKey",
"in": "header",
"name": "x-apiKey"
},
"sdCookie": {
"type": "apiKey",
"in": "cookie",
"name": "id_token"
}
}
},
"security": [{"apiKey": []}, {"sdCookie": []}],
"paths": {
"/": {
"get": {
"summary": "Lister les jeux de données.",
"operationId": "listDatasets",
"tags": ["Jeux de données"],
"parameters": [{
"in": "header",
"name": "x-apiKey",
"schema": {
"type": "string"
}
}],
"responses": {
"200": {
"content": {
Expand All @@ -41,13 +49,6 @@
"summary": "Charger un jeu de données",
"operationId": "postDataset",
"tags": ["Jeux de données"],
"parameters": [{
"in": "header",
"name": "x-apiKey",
"schema": {
"type": "string"
}
}],
"requestBody": {
"description": "Fichier à charger et métadonnées",
"required": true,
Expand Down

0 comments on commit 9c5000a

Please sign in to comment.