refactored javascript and template files into components
parent
137e5e5ca1
commit
991f37a1e6
|
@ -5,9 +5,9 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script type="text/javascript" src="resources/bootstrap2/js/bootstrap.js"></script>
|
||||
<script type="text/javascript" src="resources/js/underscore.js"></script>
|
||||
<script type="text/javascript" src="resources/js/backbone.js"></script>
|
||||
<script type="text/javascript" src="resources/js/purl.js"></script>
|
||||
<script type="text/javascript" src="resources/js/lib/underscore.js"></script>
|
||||
<script type="text/javascript" src="resources/js/lib/backbone.js"></script>
|
||||
<script type="text/javascript" src="resources/js/lib/purl.js"></script>
|
||||
<c:if test="${js != null && js != ''}">
|
||||
<script type="text/javascript" src="${js}"></script>
|
||||
</c:if>
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<link rel="apple-touch-icon-precomposed" href="../bootstrap2/ico/apple-touch-icon-57-precomposed.png">
|
||||
|
||||
<!-- Load jQuery up here so that we can use in-page functions -->
|
||||
<script type="text/javascript" src="resources/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="resources/js/lib/jquery.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,451 @@
|
|||
var ClientModel = Backbone.Model.extend({
|
||||
|
||||
idAttribute: "id",
|
||||
|
||||
initialize: function () {
|
||||
|
||||
// bind validation errors to dom elements
|
||||
// this will display form elements in red if they are not valid
|
||||
this.bind('error', function(model, errs) {
|
||||
_.map(errs, function (val, elID) {
|
||||
$('#' + elID).addClass('error');
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// We can pass it default values.
|
||||
defaults:{
|
||||
id:null,
|
||||
idTokenValiditySeconds: 600,
|
||||
clientName:"",
|
||||
clientSecret:"",
|
||||
registeredRedirectUri:[],
|
||||
authorizedGrantTypes:["authorization_code"],
|
||||
scope:[],
|
||||
authorities:[],
|
||||
clientDescription:"",
|
||||
logoUrl:"",
|
||||
clientId:"",
|
||||
allowRefresh:false,
|
||||
accessTokenValiditySeconds: 3600,
|
||||
refreshTokenValiditySeconds: 604800,
|
||||
displayClientSecret: false,
|
||||
generateClientSecret: false,
|
||||
requireClientSecret: true,
|
||||
allowIntrospection: false
|
||||
},
|
||||
|
||||
urlRoot:"api/clients"
|
||||
|
||||
});
|
||||
|
||||
var ClientCollection = Backbone.Collection.extend({
|
||||
|
||||
initialize: function() {
|
||||
//this.fetch();
|
||||
},
|
||||
|
||||
model:ClientModel,
|
||||
url:"api/clients",
|
||||
|
||||
getByClientId: function(clientId) {
|
||||
var clients = this.where({clientId: clientId});
|
||||
if (clients.length == 1) {
|
||||
return clients[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ClientView = Backbone.View.extend({
|
||||
|
||||
tagName: 'tr',
|
||||
|
||||
initialize:function () {
|
||||
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-client').html());
|
||||
}
|
||||
|
||||
if (!this.scopeTemplate) {
|
||||
this.scopeTemplate = _.template($('#tmpl-scope-list').html());
|
||||
}
|
||||
|
||||
this.model.bind('change', this.render, this);
|
||||
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
|
||||
$('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scope'), systemScopes: app.systemScopeList}));
|
||||
|
||||
this.$('.dynamically-registered').tooltip({title: 'This client was dynamically registered'});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
events:{
|
||||
"click .btn-edit":"editClient",
|
||||
"click .btn-delete":"deleteClient",
|
||||
"click .btn-whitelist":"whiteListClient"
|
||||
},
|
||||
|
||||
editClient:function () {
|
||||
app.navigate('admin/client/' + this.model.id, {trigger: true});
|
||||
},
|
||||
|
||||
whiteListClient:function() {
|
||||
var whiteList = app.whiteListList.getByClientId(this.model.get('clientId'));
|
||||
if (whiteList == null) {
|
||||
// create a new one
|
||||
app.navigate('admin/whitelist/new/' + this.model.id, {trigger: true});
|
||||
} else {
|
||||
// edit the existing one
|
||||
app.navigate('admin/whitelist/' + whiteList.id, {trigger: true});
|
||||
}
|
||||
},
|
||||
|
||||
deleteClient:function () {
|
||||
|
||||
if (confirm("Are you sure sure you would like to delete this client?")) {
|
||||
var self = this;
|
||||
|
||||
this.model.destroy({
|
||||
success:function () {
|
||||
self.$el.fadeTo("fast", 0.00, function () { //fade
|
||||
$(this).slideUp("fast", function () { //slide up
|
||||
$(this).remove(); //then remove from the DOM
|
||||
app.clientListView.togglePlaceholder();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.clientListView.delegateEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
close:function () {
|
||||
$(this.el).unbind();
|
||||
$(this.el).empty();
|
||||
}
|
||||
});
|
||||
|
||||
var ClientListView = Backbone.View.extend({
|
||||
|
||||
tagName: 'span',
|
||||
|
||||
initialize:function () {
|
||||
//this.model.bind("reset", this.render, this);
|
||||
},
|
||||
|
||||
events:{
|
||||
"click .new-client":"newClient",
|
||||
"click .refresh-table":"refreshTable"
|
||||
},
|
||||
|
||||
newClient:function () {
|
||||
this.remove();
|
||||
app.navigate('admin/client/new', {trigger: true});
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
|
||||
// append and render table structure
|
||||
$(this.el).html($('#tmpl-client-table').html());
|
||||
|
||||
_.each(this.model.models, function (client) {
|
||||
$("#client-table",this.el).append(new ClientView({model:client}).render().el);
|
||||
}, this);
|
||||
|
||||
this.togglePlaceholder();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
togglePlaceholder:function() {
|
||||
if (this.model.length > 0) {
|
||||
$('#client-table', this.el).show();
|
||||
$('#client-table-empty', this.el).hide();
|
||||
} else {
|
||||
$('#client-table', this.el).hide();
|
||||
$('#client-table-empty', this.el).show();
|
||||
}
|
||||
},
|
||||
|
||||
refreshTable:function() {
|
||||
var _self = this;
|
||||
this.model.fetch({
|
||||
success: function() {
|
||||
_self.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var ClientFormView = Backbone.View.extend({
|
||||
|
||||
tagName:"span",
|
||||
|
||||
initialize:function () {
|
||||
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-client-form').html());
|
||||
}
|
||||
|
||||
this.registeredRedirectUriCollection = new Backbone.Collection();
|
||||
this.scopeCollection = new Backbone.Collection();
|
||||
},
|
||||
|
||||
events:{
|
||||
"click .btn-save":"saveClient",
|
||||
"click #allowRefresh" : "toggleRefreshTokenTimeout",
|
||||
"click #disableAccessTokenTimeout" : function(){ $("#access-token-timeout-seconds", this.$el).prop('disabled',!$("#access-token-timeout-seconds", this.$el).prop('disabled')); },
|
||||
"click #disableIDTokenTimeout" : function(){ $("#id-token-timeout-seconds", this.$el).prop('disabled',!$("#id-token-timeout-seconds", this.$el).prop('disabled')); },
|
||||
"click #disableRefreshTokenTimeout" : function(){ $("#refresh-token-timeout-seconds", this.$el).prop('disabled',!$("#refresh-token-timeout-seconds", this.$el).prop('disabled')); },
|
||||
"click .btn-cancel": function() { window.history.back(); return false; },
|
||||
"change #requireClientSecret":"toggleRequireClientSecret",
|
||||
"change #displayClientSecret":"toggleDisplayClientSecret",
|
||||
"change #generateClientSecret":"toggleGenerateClientSecret",
|
||||
"change #logoUrl input":"previewLogo"
|
||||
},
|
||||
|
||||
toggleRefreshTokenTimeout:function () {
|
||||
$("#refreshTokenValiditySeconds", this.$el).toggle();
|
||||
},
|
||||
|
||||
previewLogo:function(event) {
|
||||
if ($('#logoUrl input', this.el).val()) {
|
||||
$('#logoPreview', this.el).empty();
|
||||
$('#logoPreview', this.el).attr('src', $('#logoUrl input').val());
|
||||
} else {
|
||||
$('#logoBlock', this.el).hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the form based on the current state of the requireClientSecret checkbox parameter
|
||||
* @param event
|
||||
*/
|
||||
toggleRequireClientSecret:function(event) {
|
||||
|
||||
if ($('#requireClientSecret input', this.el).is(':checked')) {
|
||||
// client secret is required, show all the bits
|
||||
$('#clientSecretPanel', this.el).show();
|
||||
// this function sets up the display portions
|
||||
this.toggleGenerateClientSecret();
|
||||
} else {
|
||||
// no client secret, hide all the bits
|
||||
$('#clientSecretPanel', this.el).hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the form based on the "Generate" checkbox
|
||||
* @param event
|
||||
*/
|
||||
toggleGenerateClientSecret:function(event) {
|
||||
|
||||
if ($('#generateClientSecret input', this.el).is(':checked')) {
|
||||
// show the "generated" block, hide the "display" checkbox
|
||||
$('#displayClientSecret', this.el).hide();
|
||||
$('#clientSecret', this.el).hide();
|
||||
$('#clientSecretGenerated', this.el).show();
|
||||
$('#clientSecretHidden', this.el).hide();
|
||||
} else {
|
||||
// show the display checkbox, fall back to the "display" logic
|
||||
$('#displayClientSecret', this.el).show();
|
||||
this.toggleDisplayClientSecret(event);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle whether or not to display the client secret
|
||||
* @param event
|
||||
*/
|
||||
toggleDisplayClientSecret:function(event) {
|
||||
|
||||
if ($('#displayClientSecret input').is(':checked')) {
|
||||
// want to display it
|
||||
$('#clientSecret', this.el).show();
|
||||
$('#clientSecretHidden', this.el).hide();
|
||||
$('#clientSecretGenerated', this.el).hide();
|
||||
} else {
|
||||
// want to hide it
|
||||
$('#clientSecret', this.el).hide();
|
||||
$('#clientSecretHidden', this.el).show();
|
||||
$('#clientSecretGenerated', this.el).hide();
|
||||
}
|
||||
},
|
||||
|
||||
getFormTokenValue:function(value) {
|
||||
if (value == "") return null;
|
||||
else return value;
|
||||
},
|
||||
|
||||
// maps from a form-friendly name to the real grant parameter name
|
||||
authorizedGrantMap:{
|
||||
"authorization_code": "authorization_code",
|
||||
"password": "password",
|
||||
"implicit": "implicit",
|
||||
"client_credentials": "client_credentials",
|
||||
"redelegate": "urn:ietf:params:oauth:grant_type:redelegate",
|
||||
"refresh_token": "refresh_token"
|
||||
},
|
||||
|
||||
saveClient:function (event) {
|
||||
|
||||
$('.control-group').removeClass('error');
|
||||
|
||||
// build the scope object
|
||||
var scopes = this.scopeCollection.pluck("item");
|
||||
|
||||
// build the grant type object
|
||||
var authorizedGrantTypes = [];
|
||||
$.each(this.authorizedGrantMap, function(index,type) {
|
||||
if ($('#authorizedGrantTypes-' + index).is(':checked')) {
|
||||
authorizedGrantTypes.push(type);
|
||||
}
|
||||
});
|
||||
|
||||
var requireClientSecret = $('#requireClientSecret input').is(':checked');
|
||||
var generateClientSecret = $('#generateClientSecret input').is(':checked');
|
||||
var clientSecret = null;
|
||||
|
||||
if (requireClientSecret && !generateClientSecret) {
|
||||
// if it's required but we're not generating it, send the value
|
||||
clientSecret = $('#clientSecret input').val();
|
||||
}
|
||||
|
||||
var accessTokenValiditySeconds = null;
|
||||
if (!$('disableAccessTokenTimeout').is(':checked')) {
|
||||
accessTokenValiditySeconds = this.getFormTokenValue($('#accessTokenValiditySeconds input[type=text]').val());
|
||||
}
|
||||
|
||||
var idTokenValiditySeconds = null;
|
||||
if (!$('disableIDTokenTimeout').is(':checked')) {
|
||||
idTokenValiditySeconds = this.getFormTokenValue($('#idTokenValiditySeconds input[type=text]').val());
|
||||
}
|
||||
|
||||
var refreshTokenValiditySeconds = null;
|
||||
if ($('#allowRefresh').is(':checked')) {
|
||||
|
||||
if ($.inArray('refresh_token', authorizedGrantTypes) == -1) {
|
||||
authorizedGrantTypes.push('refresh_token');
|
||||
}
|
||||
|
||||
if ($.inArray('offline_access', scopes) == -1) {
|
||||
scopes.push("offline_access");
|
||||
}
|
||||
|
||||
if (!$('disableRefreshTokenTimeout').is(':checked')) {
|
||||
refreshTokenValiditySeconds = this.getFormTokenValue($('#refreshTokenValiditySeconds input[type=text]').val());
|
||||
}
|
||||
}
|
||||
|
||||
var valid = this.model.set({
|
||||
clientName:$('#clientName input').val(),
|
||||
clientId:$('#clientId input').val(),
|
||||
clientSecret: clientSecret,
|
||||
generateClientSecret:generateClientSecret,
|
||||
registeredRedirectUri: this.registeredRedirectUriCollection.pluck("item"),
|
||||
clientDescription:$('#clientDescription textarea').val(),
|
||||
logoUrl:$('#logoUrl input').val(),
|
||||
authorizedGrantTypes: authorizedGrantTypes,
|
||||
accessTokenValiditySeconds: accessTokenValiditySeconds,
|
||||
refreshTokenValiditySeconds: refreshTokenValiditySeconds,
|
||||
idTokenValiditySeconds: idTokenValiditySeconds,
|
||||
allowRefresh: $('#allowRefresh').is(':checked'),
|
||||
allowIntrospection: $('#allowIntrospection input').is(':checked'),
|
||||
scope: scopes
|
||||
});
|
||||
|
||||
// post-validate
|
||||
// TODO: move these into the validation function somehow?
|
||||
if (this.model.get("allowRefresh") == false) {
|
||||
this.model.set("refreshTokenValiditySeconds",null);
|
||||
}
|
||||
|
||||
if ($('#disableIDTokenTimeout').is(':checked')) {
|
||||
this.model.set("idTokenValiditySeconds",null);
|
||||
}
|
||||
|
||||
if ($('#disableAccessTokenTimeout').is(':checked')) {
|
||||
this.model.set("accessTokenValiditySeconds",null);
|
||||
}
|
||||
|
||||
if ($('#disableRefreshTokenTimeout').is(':checked')) {
|
||||
this.model.set("refreshTokenValiditySeconds",null);
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
|
||||
var _self = this;
|
||||
this.model.save({}, {
|
||||
success:function () {
|
||||
app.clientList.add(_self.model);
|
||||
app.navigate('admin/clients', {trigger:true});
|
||||
},
|
||||
error:function (model,resp) {
|
||||
console.error("Oops! The object didn't save correctly.",resp);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
|
||||
$(this.el).html(this.template(this.model.toJSON()));
|
||||
|
||||
|
||||
var _self = this;
|
||||
|
||||
// build and bind registered redirect URI collection and view
|
||||
_.each(this.model.get("registeredRedirectUri"), function (registeredRedirectUri) {
|
||||
_self.registeredRedirectUriCollection.add(new URIModel({item:registeredRedirectUri}));
|
||||
});
|
||||
|
||||
$("#registeredRedirectUri .controls",this.el).html(new ListWidgetView({type:'uri', placeholder: 'http://',
|
||||
collection: this.registeredRedirectUriCollection}).render().el);
|
||||
|
||||
_self = this;
|
||||
// build and bind scopes
|
||||
_.each(this.model.get("scope"), function (scope) {
|
||||
_self.scopeCollection.add(new Backbone.Model({item:scope}));
|
||||
});
|
||||
|
||||
$("#scope .controls",this.el).html(new ListWidgetView({placeholder: 'new scope here'
|
||||
, autocomplete: _.uniq(_.flatten(app.systemScopeList.pluck("value"))) // TODO: load from default scopes
|
||||
, collection: this.scopeCollection}).render().el);
|
||||
|
||||
if (!this.model.get("allowRefresh")) {
|
||||
$("#refreshTokenValiditySeconds", this.$el).hide();
|
||||
}
|
||||
|
||||
if (this.model.get("accessTokenValiditySeconds") == null) {
|
||||
$("#access-token-timeout-seconds", this.$el).prop('disabled',true);
|
||||
}
|
||||
|
||||
if (this.model.get("refreshTokenValiditySeconds") == null) {
|
||||
$("#refresh-token-timeout-seconds", this.$el).prop('disabled',true);
|
||||
}
|
||||
|
||||
if (this.model.get("idTokenValiditySeconds") == null) {
|
||||
$("#id-token-timeout-seconds", this.$el).prop('disabled',true);
|
||||
}
|
||||
|
||||
this.toggleRequireClientSecret();
|
||||
this.previewLogo();
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
var ApprovedSiteModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
|
||||
initialize: function() { },
|
||||
|
||||
urlRoot: 'api/approved'
|
||||
|
||||
});
|
||||
|
||||
var ApprovedSiteCollection = Backbone.Collection.extend({
|
||||
initialize: function() { },
|
||||
|
||||
model: ApprovedSiteModel,
|
||||
url: 'api/approved'
|
||||
});
|
||||
|
||||
|
||||
var ApprovedSiteListView = Backbone.View.extend({
|
||||
tagName: 'span',
|
||||
|
||||
initialize:function() { },
|
||||
|
||||
events: {
|
||||
"click .refresh-table":"refreshTable"
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
$(this.el).html($('#tmpl-grant-table').html());
|
||||
|
||||
_.each(this.model.models, function(approvedSite) {
|
||||
// look up client
|
||||
var client = app.clientList.getByClientId(approvedSite.get('clientId'));
|
||||
|
||||
if (client != null) {
|
||||
|
||||
if (approvedSite.get('whitelistedSite') != null) {
|
||||
$('#grant-whitelist-table', this.el).append(new ApprovedSiteView({model: approvedSite, client: client}).render().el);
|
||||
} else {
|
||||
$('#grant-table', this.el).append(new ApprovedSiteView({model: approvedSite, client: client}).render().el);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}, this);
|
||||
|
||||
this.togglePlaceholder();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
togglePlaceholder:function() {
|
||||
// count the whitelisted and non-whitelisted entries
|
||||
var wl = 0;
|
||||
var gr = 0;
|
||||
for (var i = 0; i < this.model.length; i++) {
|
||||
if (this.model.at(i).get('whitelistedSite') != null) {
|
||||
wl += 1;
|
||||
} else {
|
||||
gr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wl > 0) {
|
||||
$('#grant-whitelist-table', this.el).show();
|
||||
$('#grant-whitelist-table-empty', this.el).hide();
|
||||
} else {
|
||||
$('#grant-whitelist-table', this.el).hide();
|
||||
$('#grant-whitelist-table-empty', this.el).show();
|
||||
}
|
||||
if (gr > 0) {
|
||||
$('#grant-table', this.el).show();
|
||||
$('#grant-table-empty', this.el).hide();
|
||||
} else {
|
||||
$('#grant-table', this.el).hide();
|
||||
$('#grant-table-empty', this.el).show();
|
||||
}
|
||||
},
|
||||
|
||||
refreshTable:function() {
|
||||
var _self = this;
|
||||
this.model.fetch({
|
||||
success: function() {
|
||||
_self.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var ApprovedSiteView = Backbone.View.extend({
|
||||
tagName: 'tr',
|
||||
|
||||
initialize: function() {
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-grant').html());
|
||||
}
|
||||
if (!this.scopeTemplate) {
|
||||
this.scopeTemplate = _.template($('#tmpl-scope-list').html());
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var json = {grant: this.model.toJSON(), client: this.options.client.toJSON()};
|
||||
|
||||
this.$el.html(this.template(json));
|
||||
|
||||
$('.scope-list', this.el).html(this.scopeTemplate({scopes: this.options.client.get('scope'), systemScopes: app.systemScopeList}));
|
||||
|
||||
this.$('.dynamically-registered').tooltip({title: 'This client was dynamically registered'});
|
||||
this.$('.whitelisted-site').tooltip({title: 'This site was whitelisted by an adminstrator'});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .btn-delete': 'deleteApprovedSite'
|
||||
},
|
||||
|
||||
deleteApprovedSite:function() {
|
||||
if (confirm("Are you sure you want to revoke access to this site?")) {
|
||||
var self = this;
|
||||
|
||||
this.model.destroy({
|
||||
success:function () {
|
||||
self.$el.fadeTo("fast", 0.00, function () { //fade
|
||||
$(this).slideUp("fast", function () { //slide up
|
||||
$(this).remove(); //then remove from the DOM
|
||||
app.approvedSiteListView.togglePlaceholder();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.approvedSiteListView.delegateEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
close:function() {
|
||||
$(this.el).unbind();
|
||||
$(this.el).empty();
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
var SystemScopeModel = Backbone.Model.extend({
|
||||
idAttribute: 'id',
|
||||
|
||||
defaults:{
|
||||
id:null,
|
||||
description:null,
|
||||
icon:null,
|
||||
value:null,
|
||||
defaultScope:false,
|
||||
allowDynReg:false
|
||||
},
|
||||
|
||||
urlRoot: 'api/scopes'
|
||||
});
|
||||
|
||||
var SystemScopeCollection = Backbone.Collection.extend({
|
||||
idAttribute: 'id',
|
||||
|
||||
model: SystemScopeModel,
|
||||
|
||||
url: 'api/scopes',
|
||||
|
||||
defaultScopes: function() {
|
||||
filtered = this.filter(function(scope) {
|
||||
return scope.get("defaultScope") === true;
|
||||
});
|
||||
return new SystemScopeCollection(filtered);
|
||||
},
|
||||
|
||||
getByValue: function(value) {
|
||||
var scopes = this.where({value: value});
|
||||
if (scopes.length == 1) {
|
||||
return scopes[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var SystemScopeView = Backbone.View.extend({
|
||||
|
||||
tagName: 'tr',
|
||||
|
||||
initialize:function () {
|
||||
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-system-scope').html());
|
||||
}
|
||||
|
||||
this.model.bind('change', this.render, this);
|
||||
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .btn-edit':'editScope',
|
||||
'click .btn-delete':'deleteScope'
|
||||
},
|
||||
|
||||
editScope:function() {
|
||||
app.navigate('admin/scope/' + this.model.id, {trigger: true});
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
|
||||
this.$('.dynamically-registered').tooltip({title: 'This client was dynamically registered'});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
deleteScope:function () {
|
||||
|
||||
if (confirm("Are you sure sure you would like to delete this scope? Clients that have this scope will still be able to ask for it.")) {
|
||||
var self = this;
|
||||
|
||||
this.model.destroy({
|
||||
success:function () {
|
||||
self.$el.fadeTo("fast", 0.00, function () { //fade
|
||||
$(this).slideUp("fast", function () { //slide up
|
||||
$(this).remove(); //then remove from the DOM
|
||||
app.systemScopeListView.togglePlaceholder();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.systemScopeListView.delegateEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
close:function () {
|
||||
$(this.el).unbind();
|
||||
$(this.el).empty();
|
||||
}
|
||||
});
|
||||
|
||||
var SystemScopeListView = Backbone.View.extend({
|
||||
tagName: 'span',
|
||||
|
||||
events:{
|
||||
"click .new-scope":"newScope",
|
||||
"click .refresh-table":"refreshTable"
|
||||
},
|
||||
|
||||
newScope:function() {
|
||||
this.remove();
|
||||
app.navigate('admin/scope/new', {trigger: true});
|
||||
},
|
||||
|
||||
refreshTable:function() {
|
||||
var _self = this;
|
||||
this.model.fetch({
|
||||
success: function() {
|
||||
_self.render();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
togglePlaceholder:function() {
|
||||
if (this.model.length > 0) {
|
||||
$('#scope-table', this.el).show();
|
||||
$('#scope-table-empty', this.el).hide();
|
||||
} else {
|
||||
$('#scope-table', this.el).hide();
|
||||
$('#scope-table-empty', this.el).show();
|
||||
}
|
||||
},
|
||||
|
||||
render: function (eventName) {
|
||||
|
||||
// append and render the table structure
|
||||
$(this.el).html($('#tmpl-system-scope-table').html());
|
||||
|
||||
_.each(this.model.models, function (scope) {
|
||||
$("#scope-table", this.el).append(new SystemScopeView({model: scope}).render().el);
|
||||
}, this);
|
||||
|
||||
this.togglePlaceholder();
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var SystemScopeFormView = Backbone.View.extend({
|
||||
tagName: 'span',
|
||||
|
||||
initialize:function() {
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-system-scope-form').html());
|
||||
}
|
||||
if (!this.iconTemplate) {
|
||||
this.iconTemplate = _.template($('#tmpl-system-scope-icon').html());
|
||||
}
|
||||
|
||||
// initialize our icon set into slices for the selector
|
||||
if (!this.bootstrapIcons) {
|
||||
this.bootstrapIcons = [];
|
||||
|
||||
var iconList = ['glass', 'music', 'search', 'envelope', 'heart', 'star',
|
||||
'star-empty', 'user', 'film', 'th-large', 'th', 'th-list', 'ok',
|
||||
'remove', 'zoom-in', 'zoom-out', 'off', 'signal', 'cog', 'trash',
|
||||
'home', 'file', 'time', 'road', 'download-alt', 'download',
|
||||
'upload', 'inbox', 'play-circle', 'repeat', 'refresh', 'list-alt',
|
||||
'lock', 'flag', 'headphones', 'volume-off', 'volume-down',
|
||||
'volume-up', 'qrcode', 'barcode', 'tag', 'tags', 'book',
|
||||
'bookmark', 'print', 'camera', 'font', 'bold', 'italic',
|
||||
'text-height', 'text-width', 'align-left', 'align-center',
|
||||
'align-right', 'align-justify', 'list', 'indent-left',
|
||||
'indent-right', 'facetime-video', 'picture', 'pencil',
|
||||
'map-marker', 'tint', 'share', 'move', 'fast-backward', 'backward',
|
||||
'pause', 'stop', 'forward', 'step-forward', 'eject',
|
||||
'chevron-right', 'plus-sign', 'minus-sign', 'remove-sign',
|
||||
'ok-sign', 'question-sign', 'info-sign', 'screenshot',
|
||||
'remove-circle', 'ok-circle', 'ban-circle', 'arrow-left',
|
||||
'arrow-right', 'arrow-down', 'share-alt', 'resize-full',
|
||||
'resize-small', 'plus', 'asterisk', 'exclamation-sign', 'gift',
|
||||
'leaf', 'fire', 'eye-close', 'plane', 'random', 'magnet',
|
||||
'chevron-up', 'chevron-down', 'retweet', 'shopping-cart',
|
||||
'folder-close', 'folder-open', 'resize-vertical',
|
||||
'resize-horizontal', 'hdd', 'bell', 'thumbs-up', 'hand-right',
|
||||
'hand-left', 'hand-down', 'circle-arrow-left', 'circle-arrow-up',
|
||||
'circle-arrow-down', 'globe', 'tasks', 'briefcase' ];
|
||||
|
||||
var size = 3;
|
||||
while (iconList.length > 0) {
|
||||
this.bootstrapIcons.push(iconList.splice(0, size));
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
events:{
|
||||
'click .btn-save':'saveScope',
|
||||
'click .btn-cancel': function() {app.navigate('admin/scope', {trigger: true}); },
|
||||
'click .btn-icon':'selectIcon'
|
||||
},
|
||||
|
||||
saveScope:function(event) {
|
||||
|
||||
var value = $('#value input').val();
|
||||
|
||||
if (value == null || value.trim() == "") {
|
||||
// error: can't have a blank scope
|
||||
return false;
|
||||
}
|
||||
|
||||
var valid = this.model.set({
|
||||
value:value,
|
||||
description:$('#description textarea').val(),
|
||||
icon:$('#iconDisplay input').val(),
|
||||
defaultScope:$('#defaultScope input').is(':checked'),
|
||||
allowDynReg:$('#allowDynReg input').is(':checked')
|
||||
});
|
||||
|
||||
if (valid) {
|
||||
var _self = this;
|
||||
this.model.save({}, {
|
||||
success:function() {
|
||||
app.systemScopeList.add(_self.model);
|
||||
app.navigate('admin/scope', {trigger: true});
|
||||
},
|
||||
error:function(model,resp) {
|
||||
console.error("The scope didn't save correctly.", resp);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
selectIcon:function(event) {
|
||||
|
||||
var icon = event.target.value;
|
||||
|
||||
$('#iconDisplay input').val(icon);
|
||||
$('#iconDisplay span').html(icon);
|
||||
$('#iconDisplay i').removeClass();
|
||||
$('#iconDisplay i').addClass('icon-' + icon);
|
||||
|
||||
$('#iconSelector').modal('hide');
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
render: function(eventName) {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
|
||||
_.each(this.bootstrapIcons, function (items) {
|
||||
$(".modal-body", this.el).append(this.iconTemplate({items:items}));
|
||||
}, this);
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
var WhiteListModel = Backbone.Model.extend({
|
||||
|
||||
idAttribute: "id",
|
||||
|
||||
initialize: function () { },
|
||||
|
||||
urlRoot: "api/whitelist"
|
||||
|
||||
});
|
||||
|
||||
var WhiteListCollection = Backbone.Collection.extend({
|
||||
initialize: function() {
|
||||
//this.fetch();
|
||||
},
|
||||
|
||||
getByClientId: function(clientId) {
|
||||
var clients = this.where({clientId: clientId});
|
||||
if (clients.length == 1) {
|
||||
return clients[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
model: WhiteListModel,
|
||||
url: "api/whitelist"
|
||||
|
||||
});
|
||||
|
||||
var WhiteListListView = Backbone.View.extend({
|
||||
tagName: 'span',
|
||||
|
||||
initialize:function () {
|
||||
//this.model.bind("reset", this.render, this);
|
||||
},
|
||||
|
||||
events:{
|
||||
"click .refresh-table":"refreshTable"
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
$(this.el).html($('#tmpl-whitelist-table').html());
|
||||
|
||||
_.each(this.model.models, function (whiteList) {
|
||||
|
||||
// look up client
|
||||
var client = app.clientList.getByClientId(whiteList.get('clientId'));
|
||||
|
||||
// if there's no client ID, this is an error!
|
||||
if (client != null) {
|
||||
$('#whitelist-table', this.el).append(new WhiteListView({model: whiteList, client: client}).render().el);
|
||||
}
|
||||
|
||||
}, this);
|
||||
|
||||
this.togglePlaceholder();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
togglePlaceholder:function() {
|
||||
if (this.model.length > 0) {
|
||||
$('#whitelist-table', this.el).show();
|
||||
$('#whitelist-table-empty', this.el).hide();
|
||||
} else {
|
||||
$('#whitelist-table', this.el).hide();
|
||||
$('#whitelist-table-empty', this.el).show();
|
||||
}
|
||||
},
|
||||
|
||||
refreshTable:function() {
|
||||
var _self = this;
|
||||
this.model.fetch({
|
||||
success: function() {
|
||||
_self.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var WhiteListView = Backbone.View.extend({
|
||||
tagName: 'tr',
|
||||
|
||||
initialize:function() {
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-whitelist').html());
|
||||
}
|
||||
|
||||
if (!this.scopeTemplate) {
|
||||
this.scopeTemplate = _.template($('#tmpl-scope-list').html());
|
||||
}
|
||||
|
||||
this.model.bind('change', this.render, this);
|
||||
},
|
||||
|
||||
render:function(eventName) {
|
||||
|
||||
var json = {whiteList: this.model.toJSON(), client: this.options.client.toJSON()};
|
||||
|
||||
this.$el.html(this.template(json));
|
||||
|
||||
$('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('allowedScopes'), systemScopes: app.systemScopeList}));
|
||||
|
||||
this.$('.dynamically-registered').tooltip({title: 'This client was dynamically registered'});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
events:{
|
||||
'click .btn-edit': 'editWhitelist',
|
||||
'click .btn-delete': 'deleteWhitelist'
|
||||
},
|
||||
|
||||
editWhitelist:function() {
|
||||
app.navigate('admin/whitelist/' + this.model.id, {trigger: true});
|
||||
},
|
||||
|
||||
deleteWhitelist:function() {
|
||||
|
||||
if (confirm("Are you sure you want to delete this whitelist entry?")) {
|
||||
var self = this;
|
||||
|
||||
this.model.destroy({
|
||||
success:function () {
|
||||
self.$el.fadeTo("fast", 0.00, function () { //fade
|
||||
$(this).slideUp("fast", function () { //slide up
|
||||
$(this).remove(); //then remove from the DOM
|
||||
// check the placeholder in case it's empty now
|
||||
app.whiteListListView.togglePlaceholder();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.whiteListListView.delegateEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
close:function() {
|
||||
$(this.el).unbind();
|
||||
$(this.el).empty();
|
||||
}
|
||||
});
|
||||
|
||||
var WhiteListFormView = Backbone.View.extend({
|
||||
tagName: 'span',
|
||||
|
||||
initialize:function () {
|
||||
if (!this.template) {
|
||||
this.template = _.template($('#tmpl-whitelist-form').html());
|
||||
}
|
||||
|
||||
this.scopeCollection = new Backbone.Collection();
|
||||
},
|
||||
|
||||
events:{
|
||||
'click .btn-save':'saveWhiteList',
|
||||
'click .btn-cancel':'cancelWhiteList',
|
||||
|
||||
},
|
||||
|
||||
saveWhiteList:function (event) {
|
||||
$('.control-group').removeClass('error');
|
||||
|
||||
// process allowed scopes
|
||||
var allowedScopes = this.scopeCollection.pluck("item");
|
||||
|
||||
if (this.model.get('id') == null) {
|
||||
this.model.set({clientId:$('#clientId input').val()});
|
||||
}
|
||||
|
||||
var valid = this.model.set({
|
||||
allowedScopes: allowedScopes
|
||||
});
|
||||
|
||||
if (valid) {
|
||||
var _self = this;
|
||||
this.model.save({}, {
|
||||
success:function () {
|
||||
app.whiteListList.add(_self.model);
|
||||
app.navigate('admin/whitelists', {trigger:true});
|
||||
},
|
||||
error:function (model,resp) {
|
||||
console.error("Oops! The object didn't save correctly.",resp);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
cancelWhiteList:function(event) {
|
||||
app.navigate('admin/whitelists', {trigger:true});
|
||||
},
|
||||
|
||||
render:function (eventName) {
|
||||
|
||||
var json = {whiteList: this.model.toJSON(), client: this.options.client.toJSON()};
|
||||
|
||||
this.$el.html(this.template(json));
|
||||
|
||||
|
||||
var _self = this;
|
||||
// build and bind scopes
|
||||
_.each(this.model.get("allowedScopes"), function (scope) {
|
||||
_self.scopeCollection.add(new Backbone.Model({item:scope}));
|
||||
});
|
||||
|
||||
$("#scope .controls",this.el).html(new ListWidgetView({
|
||||
placeholder: 'new scope here',
|
||||
autocomplete: this.options.client.scope,
|
||||
collection: this.scopeCollection}).render().el);
|
||||
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -1,314 +1,3 @@
|
|||
<!-- client -->
|
||||
|
||||
<script type="text/html" id="tmpl-client">
|
||||
<td>
|
||||
<% if (dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=clientId%>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=clientName%>
|
||||
<% if (clientDescription) { %>
|
||||
<blockquote><small><%=clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
<!--expandable future information-->
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-edit"><i class="icon-edit"></i> Edit</button>
|
||||
<button class="btn btn-warning btn-whitelist">Whitelist</button>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash icon-white"></i> Delete</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-client-table">
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-client"><i class="icon-plus icon-white"></i> New Client</button>
|
||||
</div>
|
||||
|
||||
<div id="client-table-empty" class="alert alert-info">
|
||||
There are no registered clients on this server.
|
||||
</div>
|
||||
|
||||
<table id="client-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-client"><i class="icon-plus icon-white"></i> New Client</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-client-form">
|
||||
|
||||
<h1><%=(id == null ? 'New' : 'Edit')%> Client</h1>
|
||||
|
||||
|
||||
<form class="form-horizontal tabbable">
|
||||
<fieldset>
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a data-target="#client-main-tab" data-toggle="tab" href="#">Main</a></li>
|
||||
<li><a data-target="#client-access-tab" data-toggle="tab" href="#">Access</a></li>
|
||||
<li><a data-target="#client-secret-tab" data-toggle="tab" href="#">Credentials</a></li>
|
||||
<li><a data-target="#client-token-tab" data-toggle="tab" href="#">Tokens</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="client-main-tab">
|
||||
|
||||
<div class="control-group" id="clientName">
|
||||
<label class="control-label">Client name</label>
|
||||
<div class="controls">
|
||||
<input value="<%=clientName%>" maxlength="100" type="text" class="" placeholder="Type something">
|
||||
<p class="help-block">Human-readable application name</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="clientId">
|
||||
<label class="control-label">Client ID</label>
|
||||
<div class="controls">
|
||||
<input value="<%=clientId%>" maxlength="100" type="text" class="" placeholder="Type something">
|
||||
<p class="help-block">Unique identifier. If you leave this blank it will be automatically generated.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="registeredRedirectUri">
|
||||
<label class="control-label">Redirect URI(s)</label>
|
||||
<div class="controls">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="clientDescription">
|
||||
<label class="control-label">Description</label>
|
||||
<div class="controls">
|
||||
<textarea class="input-xlarge" placeholder="Type a description" maxlength="200"
|
||||
rows="3"><%=clientDescription%></textarea>
|
||||
<p class="help-block">Human-readable text description</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="logoUrl">
|
||||
<label class="control-label">Logo URL</label>
|
||||
<div class="controls">
|
||||
<input placeholder="http://" value="<%=logoUrl%>" maxlength="100" type="text" class=""/>
|
||||
<p class="help-block">URL to use for a logo image</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="logoBlock">
|
||||
<label class="control-label">Logo Preview</label>
|
||||
<div class="controls">
|
||||
<img src="http://placehold.it/275x200&text=Enter a logo URL" alt="logo" id="logoPreview" width="275px" class="thumbnail" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-access-tab">
|
||||
|
||||
<div class="control-group" id="scope">
|
||||
<label class="control-label">Scope</label>
|
||||
<div class="controls">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="authorizedGrantTypes">
|
||||
<label class="control-label">Authorized Grant Types</label>
|
||||
|
||||
<div class="controls">
|
||||
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-authorization_code" type="checkbox"
|
||||
<%=($.inArray("authorization_code", authorizedGrantTypes) > -1 ? 'checked' : '')%>>
|
||||
authorization code
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-client_credentials" type="checkbox"
|
||||
<%=($.inArray("client_credentials", authorizedGrantTypes) > -1 ? 'checked' : '')%>> client
|
||||
credentials
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-password" type="checkbox" <%=($.inArray("password",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> password
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-implicit" type="checkbox" <%=($.inArray("implicit",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> implicit
|
||||
</label>
|
||||
<!--
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-refresh_token" type="checkbox" <%=($.inArray("refresh_token",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> refresh
|
||||
</label>
|
||||
-->
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-redelegate" type="checkbox" <%=($.inArray("urn:ietf:params:oauth:grant_type:redelegate",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> redelegate
|
||||
</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="allowIntrospection">
|
||||
<label class="control-label">Introspection</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(allowIntrospection == true ? 'checked' : '')%>> Allow calls to the Introspection Endpoint?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-secret-tab">
|
||||
|
||||
<div class="control-group" id="requireClientSecret">
|
||||
<label class="control-label">Client Secret</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(requireClientSecret == true ? 'checked' : '')%>> Require client secret?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="clientSecretPanel">
|
||||
|
||||
<div class="control-group" id="generateClientSecret">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(generateClientSecret == true ? 'checked' : '')%>> Generate a new client secret?
|
||||
</label>
|
||||
<p class="help-block">New secret will be generated when you click 'Save'</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="displayClientSecret">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(displayClientSecret == true ? 'checked' : '')%>> Display/edit client secret:
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<div id="clientSecret">
|
||||
<input value="<%=clientSecret%>" maxlength="100" type="text" placeholder="Type a secret">
|
||||
</div>
|
||||
<div id="clientSecretGenerated">
|
||||
<span class="uneditable-input span3">Generate on Save</span>
|
||||
</div>
|
||||
<div id="clientSecretHidden">
|
||||
<span class="uneditable-input span3">* * * * * * * * * * * *</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-token-tab">
|
||||
<div class="control-group" id="accessTokenValiditySeconds">
|
||||
<label class="control-label">Access Token Timeout</label>
|
||||
<div class="controls">
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="disableAccessTokenTimeout" <%=(accessTokenValiditySeconds == null ? 'checked' : '')%>/> Access tokens do not time out
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-append">
|
||||
<input type="text" class="" value="<%=(accessTokenValiditySeconds == null ? '' : accessTokenValiditySeconds)%>" id="access-token-timeout-seconds" size="16"><span class="add-on">seconds</span>
|
||||
</div>
|
||||
<p class="help-block">Enter this time in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="control-group" id="idTokenValiditySeconds">
|
||||
<label class="control-label">ID Token Timeout</label>
|
||||
<div class="controls">
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="disableIDTokenTimeout" <%=(idTokenValiditySeconds == null ? 'checked' : '')%>/> ID Tokens do not time out
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-append">
|
||||
<input type="text" class="" value="<%=(idTokenValiditySeconds == null ? '' : idTokenValiditySeconds)%>" id="id-token-timeout-seconds" size="16"><span
|
||||
class="add-on">seconds</span>
|
||||
</div>
|
||||
<p class="help-block">Enter this time in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Refresh Tokens</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="allowRefresh" <%=(allowRefresh == true ? 'checked' : '')%>> Refresh tokens are issued for this client
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="refreshTokenValiditySeconds">
|
||||
<div class="controls">
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="disableRefreshTokenTimeout" <%=(refreshTokenValiditySeconds == null ? 'checked' : '')%>/> Refresh tokens do not time out
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-append">
|
||||
<input type="text" class="" value="<%=(refreshTokenValiditySeconds == null ? '' : refreshTokenValiditySeconds)%>" id="refresh-token-timeout-seconds" size="16"><span class="add-on">seconds</span>
|
||||
</div>
|
||||
<p class="help-block">Enter this time in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-other-tab">
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
This page intentionally left blank.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</script>
|
||||
|
||||
<!-- breadcrumbs -->
|
||||
|
||||
<script type="text/html" id="tmpl-breadcrumbs">
|
||||
|
@ -338,199 +27,8 @@
|
|||
</tbody>
|
||||
</script>
|
||||
|
||||
<!-- whitelist -->
|
||||
|
||||
<script type="text/html" id="tmpl-whitelist">
|
||||
<td>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=whiteList.clientId%>
|
||||
<% if (client.clientDescription) { %>
|
||||
<blockquote><small><%=client.clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=client.clientName%>
|
||||
<!--expandable future information-->
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-edit"><i class="icon-edit"></i> Edit</button>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash icon-white"></i> Delete</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-whitelist-table">
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
<div id="whitelist-table-empty" class="alert alert-info">
|
||||
There are no whitelisted sites. Use the <strong>whitelist</strong> button on the client management page to create one.
|
||||
</div>
|
||||
|
||||
<table id="whitelist-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-whitelist-form">
|
||||
|
||||
<h1><%=(whiteList.id == null ? 'New' : 'Edit')%> Whitelisted Site</h1>
|
||||
|
||||
|
||||
<form class="form-horizontal">
|
||||
<fieldset>
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="clientId">
|
||||
<label class="control-label">Client</label>
|
||||
<div class="controls">
|
||||
<input type="hidden" name="clientId" value="<%= client.clientId %>" />
|
||||
<%= client.clientName != null ? client.clientName : client.clientId %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="scope">
|
||||
<label class="control-label">Allowed Scopes</label>
|
||||
<div class="controls">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</script>
|
||||
|
||||
<!-- approved sites (grants) -->
|
||||
|
||||
<script type="text/html" id="tmpl-grant-table">
|
||||
|
||||
<h2>Approved sites</h2>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
<h3>Sites you have manually approved</h3>
|
||||
|
||||
<div id="grant-table-empty" class="alert alert-info">
|
||||
You have not approved any sites.
|
||||
</div>
|
||||
|
||||
<table id="grant-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Application</th>
|
||||
<th>Created</th>
|
||||
<th>Last Accessed</th>
|
||||
<th>Expires</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well">
|
||||
|
||||
<h3>Sites that have been whitelisted by an administrator</h3>
|
||||
<p>If you revoke them here, they will automatically be re-approved on your next visit.</p>
|
||||
|
||||
<div id="grant-whitelist-table-empty" class="alert alert-info">
|
||||
You have not accessed any whitelisted sites.
|
||||
</div>
|
||||
|
||||
<table id="grant-whitelist-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Application</th>
|
||||
<th>Created</th>
|
||||
<th>Last Accessed</th>
|
||||
<th>Expires</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-grant">
|
||||
<td>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= client.clientName != null ? client.clientName : client.clientId %>
|
||||
<% if (client.clientDescription) { %>
|
||||
<blockquote><small><%=client.clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
</td>
|
||||
|
||||
|
||||
<!-- TODO: make these dates collapsable/expandable -->
|
||||
|
||||
<td>
|
||||
<%= grant.creationDate %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= grant.accessDate %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= grant.timeoutDate %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash"></i> Revoke</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<!-- blacklist -->
|
||||
<!-- blacklist form -->
|
||||
<script type="text/html" id="tmpl-blacklist-form">
|
||||
|
||||
<form class="form-horizontal">
|
||||
|
@ -554,178 +52,3 @@
|
|||
|
||||
</script>
|
||||
|
||||
<!-- system scope -->
|
||||
<script type="text/html" id = "tmpl-system-scope-table">
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-scope"><i class="icon-plus icon-white"></i> New Scope</button>
|
||||
</div>
|
||||
|
||||
<div id="scope-table-empty" class="alert alert-info">
|
||||
There are no system scopes defined. Clients may still have custom scopes.
|
||||
</div>
|
||||
|
||||
<table id="scope-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Scope</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-scope"><i class="icon-plus icon-white"></i> New Scope</button>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-system-scope">
|
||||
<td>
|
||||
<% if (icon) { %>
|
||||
<i class="icon-<%= icon %>"></i>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= value %>
|
||||
<blockquote><small><%= description %></small></blockquote>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-edit"><i class="icon-edit"></i> Edit</button>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash"></i> Delete</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-system-scope-form">
|
||||
<h1><%= id == null ? 'New' : 'Edit'%> Scope</h1>
|
||||
|
||||
<form class="form-horizontal">
|
||||
<fieldset>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="value">
|
||||
<label class="control-label">Scope value</label>
|
||||
<div class="controls">
|
||||
<input value="<%=value != null ? value : ''%>" type="text" class="" placeholder="scope">
|
||||
<p class="help-block">Single string with no spaces</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="description">
|
||||
<label class="control-label">Description</label>
|
||||
<div class="controls">
|
||||
<textarea class="input-xlarge" placeholder="Type a description" maxlength="200" rows="3"><%=description != null ? description : ''%></textarea>
|
||||
<p class="help-block">Human-readable text description</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="icon">
|
||||
<label class="control-label">Icon</label>
|
||||
<div class="controls">
|
||||
|
||||
<span id="iconDisplay">
|
||||
<i class="icon-<%=icon%>"></i> <span class="uneditable-input"><%=icon%></span>
|
||||
|
||||
<input type="hidden" value="<%=icon%>">
|
||||
</span>
|
||||
|
||||
<a href="#iconSelector" role="button" class="btn btn-info" data-toggle="modal"><i class="icon-white icon-picture"></i> Select an icon</a>
|
||||
|
||||
<div id="iconSelector" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="iconSelectorLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="iconSelectorLabel">Select an Icon</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="defaultScope">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=defaultScope ? 'checked' : '' %>> default scope
|
||||
</label>
|
||||
<p class="help-block">Newly-created clients get this scope by default?</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="allowDynReg">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=allowDynReg ? 'checked' : '' %>> allow dynamic registration
|
||||
</label>
|
||||
<p class="help-block">Allow dynamically registered clients to request this scope?</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-system-scope-icon">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span4" style="margin-top: 5px; margin-bottom: 5px;">
|
||||
<% if (items[0]) { %>
|
||||
<button class="btn btn-block btn-icon" value="<%=items[0]%>"><i class="icon-<%=items[0]%>"></i> <%=items[0]%>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="span4" style="margin-top: 5px; margin-bottom: 5px;">
|
||||
<% if (items[1]) { %>
|
||||
<button class="btn btn-block btn-icon" value="<%=items[1]%>"><i class="icon-<%=items[1]%>"></i> <%=items[1]%>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="span4" style="margin-top: 5px; margin-bottom: 5px;">
|
||||
<% if (items[2]) { %>
|
||||
<button class="btn btn-block btn-icon" value="<%=items[2]%>"><i class="icon-<%=items[2]%>"></i> <%=items[2]%>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-scope-list">
|
||||
|
||||
<%
|
||||
_.each(scopes, function(s) {
|
||||
%>
|
||||
<span class="badge badge-info">
|
||||
<%
|
||||
var ss = systemScopes.getByValue(s);
|
||||
if (ss && ss.get('icon')) {
|
||||
%>
|
||||
<i class="icon-<%=ss.get('icon')%> icon-white"></i>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
<%=s%>
|
||||
</span>
|
||||
<%
|
||||
});
|
||||
%>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,310 @@
|
|||
<!-- client -->
|
||||
|
||||
<script type="text/html" id="tmpl-client">
|
||||
<td>
|
||||
<% if (dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=clientId%>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=clientName%>
|
||||
<% if (clientDescription) { %>
|
||||
<blockquote><small><%=clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
<!--expandable future information-->
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-edit"><i class="icon-edit"></i> Edit</button>
|
||||
<button class="btn btn-warning btn-whitelist">Whitelist</button>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash icon-white"></i> Delete</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-client-table">
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-client"><i class="icon-plus icon-white"></i> New Client</button>
|
||||
</div>
|
||||
|
||||
<div id="client-table-empty" class="alert alert-info">
|
||||
There are no registered clients on this server.
|
||||
</div>
|
||||
|
||||
<table id="client-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-client"><i class="icon-plus icon-white"></i> New Client</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-client-form">
|
||||
|
||||
<h1><%=(id == null ? 'New' : 'Edit')%> Client</h1>
|
||||
|
||||
|
||||
<form class="form-horizontal tabbable">
|
||||
<fieldset>
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a data-target="#client-main-tab" data-toggle="tab" href="#">Main</a></li>
|
||||
<li><a data-target="#client-access-tab" data-toggle="tab" href="#">Access</a></li>
|
||||
<li><a data-target="#client-secret-tab" data-toggle="tab" href="#">Credentials</a></li>
|
||||
<li><a data-target="#client-token-tab" data-toggle="tab" href="#">Tokens</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="client-main-tab">
|
||||
|
||||
<div class="control-group" id="clientName">
|
||||
<label class="control-label">Client name</label>
|
||||
<div class="controls">
|
||||
<input value="<%=clientName%>" maxlength="100" type="text" class="" placeholder="Type something">
|
||||
<p class="help-block">Human-readable application name</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="clientId">
|
||||
<label class="control-label">Client ID</label>
|
||||
<div class="controls">
|
||||
<input value="<%=clientId%>" maxlength="100" type="text" class="" placeholder="Type something">
|
||||
<p class="help-block">Unique identifier. If you leave this blank it will be automatically generated.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="registeredRedirectUri">
|
||||
<label class="control-label">Redirect URI(s)</label>
|
||||
<div class="controls">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="clientDescription">
|
||||
<label class="control-label">Description</label>
|
||||
<div class="controls">
|
||||
<textarea class="input-xlarge" placeholder="Type a description" maxlength="200"
|
||||
rows="3"><%=clientDescription%></textarea>
|
||||
<p class="help-block">Human-readable text description</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="logoUrl">
|
||||
<label class="control-label">Logo URL</label>
|
||||
<div class="controls">
|
||||
<input placeholder="http://" value="<%=logoUrl%>" maxlength="100" type="text" class=""/>
|
||||
<p class="help-block">URL to use for a logo image</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="logoBlock">
|
||||
<label class="control-label">Logo Preview</label>
|
||||
<div class="controls">
|
||||
<img src="http://placehold.it/275x200&text=Enter a logo URL" alt="logo" id="logoPreview" width="275px" class="thumbnail" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-access-tab">
|
||||
|
||||
<div class="control-group" id="scope">
|
||||
<label class="control-label">Scope</label>
|
||||
<div class="controls">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="authorizedGrantTypes">
|
||||
<label class="control-label">Authorized Grant Types</label>
|
||||
|
||||
<div class="controls">
|
||||
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-authorization_code" type="checkbox"
|
||||
<%=($.inArray("authorization_code", authorizedGrantTypes) > -1 ? 'checked' : '')%>>
|
||||
authorization code
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-client_credentials" type="checkbox"
|
||||
<%=($.inArray("client_credentials", authorizedGrantTypes) > -1 ? 'checked' : '')%>> client
|
||||
credentials
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-password" type="checkbox" <%=($.inArray("password",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> password
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-implicit" type="checkbox" <%=($.inArray("implicit",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> implicit
|
||||
</label>
|
||||
<!--
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-refresh_token" type="checkbox" <%=($.inArray("refresh_token",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> refresh
|
||||
</label>
|
||||
-->
|
||||
<label class="checkbox">
|
||||
<input id="authorizedGrantTypes-redelegate" type="checkbox" <%=($.inArray("urn:ietf:params:oauth:grant_type:redelegate",
|
||||
authorizedGrantTypes) > -1 ? 'checked' : '')%>> redelegate
|
||||
</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="allowIntrospection">
|
||||
<label class="control-label">Introspection</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(allowIntrospection == true ? 'checked' : '')%>> Allow calls to the Introspection Endpoint?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-secret-tab">
|
||||
|
||||
<div class="control-group" id="requireClientSecret">
|
||||
<label class="control-label">Client Secret</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(requireClientSecret == true ? 'checked' : '')%>> Require client secret?
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="clientSecretPanel">
|
||||
|
||||
<div class="control-group" id="generateClientSecret">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(generateClientSecret == true ? 'checked' : '')%>> Generate a new client secret?
|
||||
</label>
|
||||
<p class="help-block">New secret will be generated when you click 'Save'</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="displayClientSecret">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=(displayClientSecret == true ? 'checked' : '')%>> Display/edit client secret:
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<div id="clientSecret">
|
||||
<input value="<%=clientSecret%>" maxlength="100" type="text" placeholder="Type a secret">
|
||||
</div>
|
||||
<div id="clientSecretGenerated">
|
||||
<span class="uneditable-input span3">Generate on Save</span>
|
||||
</div>
|
||||
<div id="clientSecretHidden">
|
||||
<span class="uneditable-input span3">* * * * * * * * * * * *</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-token-tab">
|
||||
<div class="control-group" id="accessTokenValiditySeconds">
|
||||
<label class="control-label">Access Token Timeout</label>
|
||||
<div class="controls">
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="disableAccessTokenTimeout" <%=(accessTokenValiditySeconds == null ? 'checked' : '')%>/> Access tokens do not time out
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-append">
|
||||
<input type="text" class="" value="<%=(accessTokenValiditySeconds == null ? '' : accessTokenValiditySeconds)%>" id="access-token-timeout-seconds" size="16"><span class="add-on">seconds</span>
|
||||
</div>
|
||||
<p class="help-block">Enter this time in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="control-group" id="idTokenValiditySeconds">
|
||||
<label class="control-label">ID Token Timeout</label>
|
||||
<div class="controls">
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="disableIDTokenTimeout" <%=(idTokenValiditySeconds == null ? 'checked' : '')%>/> ID Tokens do not time out
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-append">
|
||||
<input type="text" class="" value="<%=(idTokenValiditySeconds == null ? '' : idTokenValiditySeconds)%>" id="id-token-timeout-seconds" size="16"><span
|
||||
class="add-on">seconds</span>
|
||||
</div>
|
||||
<p class="help-block">Enter this time in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">Refresh Tokens</label>
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="allowRefresh" <%=(allowRefresh == true ? 'checked' : '')%>> Refresh tokens are issued for this client
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="refreshTokenValiditySeconds">
|
||||
<div class="controls">
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="disableRefreshTokenTimeout" <%=(refreshTokenValiditySeconds == null ? 'checked' : '')%>/> Refresh tokens do not time out
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-append">
|
||||
<input type="text" class="" value="<%=(refreshTokenValiditySeconds == null ? '' : refreshTokenValiditySeconds)%>" id="refresh-token-timeout-seconds" size="16"><span class="add-on">seconds</span>
|
||||
</div>
|
||||
<p class="help-block">Enter this time in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="client-other-tab">
|
||||
|
||||
<div class="alert alert-block alert-info">
|
||||
This page intentionally left blank.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,99 @@
|
|||
<!-- approved sites (grants) -->
|
||||
|
||||
<script type="text/html" id="tmpl-grant-table">
|
||||
|
||||
<h2>Approved sites</h2>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
<h3>Sites you have manually approved</h3>
|
||||
|
||||
<div id="grant-table-empty" class="alert alert-info">
|
||||
You have not approved any sites.
|
||||
</div>
|
||||
|
||||
<table id="grant-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Application</th>
|
||||
<th>Created</th>
|
||||
<th>Last Accessed</th>
|
||||
<th>Expires</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well">
|
||||
|
||||
<h3>Sites that have been whitelisted by an administrator</h3>
|
||||
<p>If you revoke them here, they will automatically be re-approved on your next visit.</p>
|
||||
|
||||
<div id="grant-whitelist-table-empty" class="alert alert-info">
|
||||
You have not accessed any whitelisted sites.
|
||||
</div>
|
||||
|
||||
<table id="grant-whitelist-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Application</th>
|
||||
<th>Created</th>
|
||||
<th>Last Accessed</th>
|
||||
<th>Expires</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-grant">
|
||||
<td>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= client.clientName != null ? client.clientName : client.clientId %>
|
||||
<% if (client.clientDescription) { %>
|
||||
<blockquote><small><%=client.clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
</td>
|
||||
|
||||
|
||||
<!-- TODO: make these dates collapsable/expandable -->
|
||||
|
||||
<td>
|
||||
<%= grant.creationDate %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= grant.accessDate %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= grant.timeoutDate %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash"></i> Revoke</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
<!-- system scope -->
|
||||
<script type="text/html" id = "tmpl-system-scope-table">
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-scope"><i class="icon-plus icon-white"></i> New Scope</button>
|
||||
</div>
|
||||
|
||||
<div id="scope-table-empty" class="alert alert-info">
|
||||
There are no system scopes defined. Clients may still have custom scopes.
|
||||
</div>
|
||||
|
||||
<table id="scope-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Scope</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
<button class="btn btn-small btn-primary new-scope"><i class="icon-plus icon-white"></i> New Scope</button>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-system-scope">
|
||||
<td>
|
||||
<% if (icon) { %>
|
||||
<i class="icon-<%= icon %>"></i>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%= value %>
|
||||
<blockquote><small><%= description %></small></blockquote>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-edit"><i class="icon-edit"></i> Edit</button>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash"></i> Delete</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-system-scope-form">
|
||||
<h1><%= id == null ? 'New' : 'Edit'%> Scope</h1>
|
||||
|
||||
<form class="form-horizontal">
|
||||
<fieldset>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="value">
|
||||
<label class="control-label">Scope value</label>
|
||||
<div class="controls">
|
||||
<input value="<%=value != null ? value : ''%>" type="text" class="" placeholder="scope">
|
||||
<p class="help-block">Single string with no spaces</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="description">
|
||||
<label class="control-label">Description</label>
|
||||
<div class="controls">
|
||||
<textarea class="input-xlarge" placeholder="Type a description" maxlength="200" rows="3"><%=description != null ? description : ''%></textarea>
|
||||
<p class="help-block">Human-readable text description</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="icon">
|
||||
<label class="control-label">Icon</label>
|
||||
<div class="controls">
|
||||
|
||||
<span id="iconDisplay">
|
||||
<i class="icon-<%=icon%>"></i> <span class="uneditable-input"><%=icon%></span>
|
||||
|
||||
<input type="hidden" value="<%=icon%>">
|
||||
</span>
|
||||
|
||||
<a href="#iconSelector" role="button" class="btn btn-info" data-toggle="modal"><i class="icon-white icon-picture"></i> Select an icon</a>
|
||||
|
||||
<div id="iconSelector" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="iconSelectorLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="iconSelectorLabel">Select an Icon</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="defaultScope">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=defaultScope ? 'checked' : '' %>> default scope
|
||||
</label>
|
||||
<p class="help-block">Newly-created clients get this scope by default?</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="allowDynReg">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" <%=allowDynReg ? 'checked' : '' %>> allow dynamic registration
|
||||
</label>
|
||||
<p class="help-block">Allow dynamically registered clients to request this scope?</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-system-scope-icon">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span4" style="margin-top: 5px; margin-bottom: 5px;">
|
||||
<% if (items[0]) { %>
|
||||
<button class="btn btn-block btn-icon" value="<%=items[0]%>"><i class="icon-<%=items[0]%>"></i> <%=items[0]%>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="span4" style="margin-top: 5px; margin-bottom: 5px;">
|
||||
<% if (items[1]) { %>
|
||||
<button class="btn btn-block btn-icon" value="<%=items[1]%>"><i class="icon-<%=items[1]%>"></i> <%=items[1]%>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="span4" style="margin-top: 5px; margin-bottom: 5px;">
|
||||
<% if (items[2]) { %>
|
||||
<button class="btn btn-block btn-icon" value="<%=items[2]%>"><i class="icon-<%=items[2]%>"></i> <%=items[2]%>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-scope-list">
|
||||
|
||||
<%
|
||||
_.each(scopes, function(s) {
|
||||
%>
|
||||
<span class="badge badge-info">
|
||||
<%
|
||||
var ss = systemScopes.getByValue(s);
|
||||
if (ss && ss.get('icon')) {
|
||||
%>
|
||||
<i class="icon-<%=ss.get('icon')%> icon-white"></i>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
<%=s%>
|
||||
</span>
|
||||
<%
|
||||
});
|
||||
%>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,92 @@
|
|||
<!-- whitelist -->
|
||||
|
||||
<script type="text/html" id="tmpl-whitelist">
|
||||
<td>
|
||||
<% if (client.dynamicallyRegistered) { %>
|
||||
<span class="dynamically-registered"><i class="icon-globe"></i></span>
|
||||
<% } %>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=whiteList.clientId%>
|
||||
<% if (client.clientDescription) { %>
|
||||
<blockquote><small><%=client.clientDescription%></small></blockquote>
|
||||
<% } %>
|
||||
<div class="scope-list"></div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<%=client.clientName%>
|
||||
<!--expandable future information-->
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-edit"><i class="icon-edit"></i> Edit</button>
|
||||
<button class="btn btn-danger btn-delete pull-right"><i class="icon-trash icon-white"></i> Delete</button>
|
||||
</td>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-whitelist-table">
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
<div id="whitelist-table-empty" class="alert alert-info">
|
||||
There are no whitelisted sites. Use the <strong>whitelist</strong> button on the client management page to create one.
|
||||
</div>
|
||||
|
||||
<table id="whitelist-table" class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small refresh-table"><i class="icon-refresh"></i> Refresh</button>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-whitelist-form">
|
||||
|
||||
<h1><%=(whiteList.id == null ? 'New' : 'Edit')%> Whitelisted Site</h1>
|
||||
|
||||
|
||||
<form class="form-horizontal">
|
||||
<fieldset>
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="clientId">
|
||||
<label class="control-label">Client</label>
|
||||
<div class="controls">
|
||||
<input type="hidden" name="clientId" value="<%= client.clientId %>" />
|
||||
<%= client.clientName != null ? client.clientName : client.clientId %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" id="scope">
|
||||
<label class="control-label">Allowed Scopes</label>
|
||||
<div class="controls">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="well well-small">
|
||||
<button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> Save</button>
|
||||
<button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> Cancel</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</script>
|
Loading…
Reference in New Issue