[auth] Added api key and basic authorization

This commit is contained in:
Anna Bodnia
2016-03-04 20:55:57 +02:00
parent 4fdc174ea0
commit a268d007a2
24 changed files with 547 additions and 294 deletions

View File

@@ -1188,6 +1188,11 @@
text-decoration: underline;
cursor: pointer;
}
.swagger-section .auth_container {
padding: 0 0 10px;
margin-bottom: 5px;
border-bottom: solid 1px #CCC;
}
.swagger-section .auth_container .basic_auth__title {
color: #547f00;
font-size: 1.2em;
@@ -1207,9 +1212,6 @@
cursor: pointer;
outline: none;
}
.swagger-section .auth_container .key_input_container {
margin-bottom: 15px;
}
.swagger-section .auth_container .basic_auth_container {
font-size: 0.9em;
}

View File

@@ -1188,6 +1188,11 @@
text-decoration: underline;
cursor: pointer;
}
.swagger-section .auth_container {
padding: 0 0 10px;
margin-bottom: 5px;
border-bottom: solid 1px #CCC;
}
.swagger-section .auth_container .basic_auth__title {
color: #547f00;
font-size: 1.2em;
@@ -1207,9 +1212,6 @@
cursor: pointer;
outline: none;
}
.swagger-section .auth_container .key_input_container {
margin-bottom: 15px;
}
.swagger-section .auth_container .basic_auth_container {
font-size: 0.9em;
}

View File

@@ -36,7 +36,7 @@
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "http://petstore.swagger.io/v2/swagger.json";
url = "http://localhost:3001/swagger.json";
}
hljs.configure({

View File

@@ -0,0 +1,33 @@
'use strict';
SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi
events: {
'change .auth_input': 'apiKeyChange'
},
template: Handlebars.templates.apikey_auth,
initialize: function(opts) {
this.options = opts || {};
this.router = this.options.router;
},
render: function (){
this.$el.html(this.template(this.model.toJSON()));
return this;
},
apiKeyChange: function (e) {
var val = $(e.target).val();
this.model.set('valid', !!val);
this.model.set('value', val);
},
isValid: function () {
return this.get('valid');
}
});

View File

@@ -1,39 +0,0 @@
'use strict';
SwaggerUi.Views.ApiKeyButton = Backbone.View.extend({ // TODO: append this to global SwaggerUi
events:{
'click .auth_submit_button' : 'applyApiKey',
'click .auth_logout__button' : 'clickLogout'
},
template: Handlebars.templates.apikey_button_view,
initialize: function(opts) {
this.options = opts || {};
this.router = this.options.router;
},
render: function(){
this.$el.html(this.template(this.model));
return this;
},
applyApiKey: function() {
var keyAuth = new SwaggerClient.ApiKeyAuthorization(
this.model.name,
this.$('.input_apiKey_entry').val(),
this.model.in
);
this.router.api.clientAuthorizations.add(this.model.name, keyAuth);
this.router.load();
},
clickLogout: function () {
window.swaggerUi.api.clientAuthorizations.remove(this.model.name);
this.router.load();
}
});

View File

@@ -23,6 +23,7 @@ SwaggerUi.Views.AuthButtonView = Backbone.View.extend({
authorizeBtnClick: function (e) {
var authsModel;
e.preventDefault();
authsModel = {
@@ -35,30 +36,14 @@ SwaggerUi.Views.AuthButtonView = Backbone.View.extend({
},
renderAuths: function (auths) {
var name, authEl, authModel;
var el = $('<div>');
var authz = window.swaggerUi.api.clientAuthorizations.authz;
var $el = $('<div>');
for (name in auths) {
authModel = _.extend({}, auths[name]);
auths.forEach(function (auth) {
var authEl = new SwaggerUi.Views.AuthView({data: auth, router: this.router}).render().el;
$el.append(authEl);
}, this);
if (authz[name]) {
_.extend(authModel, {
isLogout: true,
value: authz[name].value
});
}
if (authModel.type === 'apiKey') {
authEl = new SwaggerUi.Views.ApiKeyButton({model: authModel, router: this.router}).render().el;
el.append(authEl);
} else if (authModel.type === 'basic' && el.find('.basic_auth_container').length === 0) {
authEl = new SwaggerUi.Views.BasicAuthButton({model: authModel, router: this.router}).render().el;
el.append(authEl);
}
}
return el;
return $el;
}
});

View File

@@ -0,0 +1,126 @@
'use strict';
SwaggerUi.Views.AuthView = Backbone.View.extend({
events: {
'click .auth_submit_button': 'authorizeClick',
'click .auth_logout__button': 'logoutClick'
},
tpls: {
main: Handlebars.templates.auth_view
},
selectors: {
innerEl: '.auth_inner'
},
initialize: function(opts) {
this.options = opts || {};
opts.data = opts.data || {};
this.router = this.options.router;
this.collection = new Backbone.Collection();
this.collection.add(this.parseData(opts.data));
this.$el.html(this.tpls.main({isLogout: this.isAuthorizedCollection()}));
this.$innerEl = this.$(this.selectors.innerEl);
},
render: function () {
this.renderAuths();
if (!this.$innerEl.html()) {
this.$el.html('');
}
return this;
},
authorizeClick: function (e) {
e.preventDefault();
if (this.isValidCollection()) {
this.authorize();
}
},
parseData: function (data) {
var authz = window.swaggerUi.api.clientAuthorizations.authz;
return _.map(data, function (auth, name) {
var isBasic = authz.basic && auth.type === 'basic';
if (authz[name] || isBasic) {
_.extend(auth, {
isLogout: true,
value: isBasic ? '' : authz[name].value,
valid: true
});
}
return auth;
});
},
renderAuths: function () {
this.collection.each(function (auth) {
this.renderOneAuth(auth);
}, this);
},
renderOneAuth: function (authModel) {
var authEl;
var type = authModel.get('type');
if (type === 'apiKey') {
authEl = new SwaggerUi.Views.ApiKeyAuthView({model: authModel, router: this.router}).render().el;
this.$innerEl.append(authEl);
} else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) {
authEl = new SwaggerUi.Views.BasicAuthView({model: authModel, router: this.router}).render().el;
this.$innerEl.append(authEl);
}
},
isValidCollection: function () {
return this.collection.length === this.collection.where({ valid: true }).length;
},
authorize: function () {
this.collection.forEach(function (auth) {
var keyAuth, basicAuth;
var type = auth.get('type');
if (type === 'apiKey') {
keyAuth = new SwaggerClient.ApiKeyAuthorization(
auth.get('name'),
auth.get('value'),
auth.get('in')
);
this.router.api.clientAuthorizations.add(auth.get('name'), keyAuth);
} else if (type === 'basic') {
basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password'));
this.router.api.clientAuthorizations.add(auth.get('type'), basicAuth);
}
}, this);
this.router.load();
},
isAuthorizedCollection: function () {
return this.collection.length === this.collection.where({ isLogout: true }).length;
},
logoutClick: function (e) {
e.preventDefault();
this.collection.forEach(function (auth) {
var name = auth.get('name');
window.swaggerUi.api.clientAuthorizations.remove(name);
});
this.router.load();
}
});

View File

@@ -1,38 +0,0 @@
'use strict';
SwaggerUi.Views.BasicAuthButton = Backbone.View.extend({
initialize: function (opts) {
this.options = opts || {};
this.router = this.options.router;
},
template: Handlebars.templates.basic_auth_button_view,
render: function(){
$(this.el).html(this.template(this.model));
return this;
},
events: {
'submit .key_input_container' : 'applyPassword',
'click .auth_logout__button' : 'clickLogout'
},
applyPassword: function(event) {
event.preventDefault();
var username = this.$('.basic_auth__username').val();
var password = this.$('.basic_auth__password').val();
var basicAuth = new SwaggerClient.PasswordAuthorization(username, password);
this.router.api.clientAuthorizations.add(this.model.type, basicAuth);
this.router.load();
},
clickLogout: function () {
window.swaggerUi.api.clientAuthorizations.remove(this.model.name);
this.router.load();
}
});

View File

@@ -0,0 +1,35 @@
'use strict';
SwaggerUi.Views.BasicAuthView = Backbone.View.extend({
initialize: function (opts) {
this.options = opts || {};
this.router = this.options.router;
},
events: {
'change .auth_input': 'inputChange'
},
template: Handlebars.templates.basic_auth,
render: function(){
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
inputChange: function (e) {
var $el = $(e.target);
var val = $el.val();
var attr = $el.prop('name');
this.model.set(attr, val);
this.model.set('valid', !!this.model.get('password') && !!this.model.get('username'));
},
isValid: function () {
return this.get('valid');
}
});

View File

@@ -12,7 +12,7 @@ SwaggerUi.Views.HeaderView = Backbone.View.extend({
showPetStore: function(){
this.trigger('update-swagger-ui', {
url:'http://petstore.swagger.io/v2/swagger.json'
url:'http://localhost:3001/swagger.json'
});
},

View File

@@ -84,13 +84,19 @@ SwaggerUi.Views.MainView = Backbone.View.extend({
render: function () {
// Render the outer container for resources
var authsModel;
var authsModel, parsedDefinitions;
$(this.el).html(Handlebars.templates.main(this.model));
this.model.securityDefinitions = this.model.securityDefinitions || {};
if (!_.isEmpty(this.model.securityDefinitions)) {
authsModel = { auths: this.model.securityDefinitions };
parsedDefinitions = _.map(this.model.securityDefinitions, function (auth, name) {
var result = {};
result[name] = auth;
return result;
});
authsModel = { auths: parsedDefinitions };
authsModel.isLogout = !_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz);
this.authView = new SwaggerUi.Views.AuthButtonView({model: authsModel, router: this.router});

View File

@@ -257,6 +257,15 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
this.addStatusCode(statusCode);
}
if (Array.isArray(this.model.security)) {
//Todo add parsing security from definitions
var authsModel = { auths: this.model.security };
authsModel.isLogout = !_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz);
this.authView = new SwaggerUi.Views.AuthButtonView({model: authsModel, router: this.router});
this.$('.authorize-wrapper').append(this.authView.render().el);
}
this.showSnippet();
return this;
},

View File

@@ -31,8 +31,11 @@
}
.auth_container {
padding: 0 0 10px;
margin-bottom: 5px;
border-bottom: solid 1px #CCC;
.basic_auth__title {
.basic_auth__title {
color: #547f00;
font-size: 1.2em;
}
@@ -53,10 +56,6 @@
outline: none;
}
.key_input_container {
margin-bottom: 15px;
}
.basic_auth_container {
font-size: 0.9em;
}

View File

@@ -0,0 +1,12 @@
<div class='key_input_container'>
<div class='auth__description'>{{description}}</div>
<div>
<span class='auth_label'><label for='input_apiKey_entry'><span>Api key</span> in {{in}}</label></span>
<span class='auth_in'><label for='input_apiKey_entry'>{{name}} =</label></span>
{{#if isLogout}}
<span class="auth_label">{{value}}</span>
{{else}}
<input placeholder='api_key' class='auth_input input_apiKey_entry' name='apiKey' type='text'/>
{{/if}}
</div>
</div>

View File

@@ -1,19 +0,0 @@
<div class='auth_container'>
<div class='key_input_container'>
<div class='auth__description'>{{description}}</div>
<div>
<span class='auth_label'><label for='input_apiKey_entry'><span>Api key</span> in {{in}}</label></span>
<span class='auth_in'><label for='input_apiKey_entry'>{{name}} =</label></span>
{{#if isLogout}}
<span class="auth_label">{{value}}</span>
{{else}}
<input placeholder='api_key' class='auth_input input_apiKey_entry' name='apiKey' type='text'/>
{{/if}}
</div>
{{#if isLogout}}
<input type="button" class="auth_logout__button" value="logout"></div>
{{else}}
<div class='auth_submit'><a class='auth_submit_button' href='#' data-sw-translate>apply</a></div>
{{/if}}
</div>
</div>

View File

@@ -0,0 +1,10 @@
<div class="auth_container">
<div class="auth_inner"></div>
{{#if isLogout}}
<input type="button" class="auth_logout__button" value="logout">
{{else}}
<div class="auth_submit"><a class="auth_submit_button" href="#" data-sw-translate>apply</a></div>
{{/if}}
</div>

View File

@@ -0,0 +1,12 @@
<div class='basic_auth_container'>
<h3 class="basic_auth__title">Basic authentication{{#if isLogout}} - authorized{{/if}}</h3>
{{#unless isLogout}}
<form class="key_input_container">
<div class="auth__description">{{description}}</div>
<div class="auth_label"><label data-sw-translate>username</label></div>
<input required placeholder="username" class="basic_auth__username auth_input" name="username" type="text"/>
<div class="auth_label"><label data-sw-translate>password</label></div>
<input required placeholder="password" class="basic_auth__password auth_input" name="password" type="password"/>
</form>
{{/unless}}
</div>

View File

@@ -1,17 +0,0 @@
<div class='auth_container basic_auth_container'>
<h3 class="basic_auth__title">Basic authentication</h3>
{{#if isLogout}}
<input type="button" class="auth_logout__button" value="logout"></div>
{{else}}
<form class="key_input_container">
<div class="auth__description">{{description}}</div>
<div class="auth_label"><label data-sw-translate>username</label></div>
<input required placeholder="username" class="basic_auth__username auth_input" name="username" type="text"/>
<div class="auth_label"><label data-sw-translate>password</label></div>
<input required placeholder="password" class="basic_auth__password auth_input" name="password" type="password"/>
<div class='auth_submit'><input type="submit" class="auth_submit__button" value="apply"></div>
</form>
{{/if}}
</div>

View File

@@ -23,6 +23,9 @@
<h4><span data-sw-translate>Implementation Notes</span></h4>
<div class="markdown">{{{description}}}</div>
{{/if}}
{{#if security}}
<div class='authorize-wrapper'></div>
{{/if}}
{{#oauth}}
<div class="auth">
<span class="api-ic ic-error">{{/oauth}}