/******************************************************************************* * Copyright 2014 The MITRE Corporation * and the MIT Kerberos and Internet Trust Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ var AccessTokenModel = Backbone.Model.extend({ idAttribute: 'id', defaults:{ id:null, value:null, idTokenId:null, refreshTokenId:null, scopes:[], clientId:null, userId:null, expiration:null }, urlRoot: 'api/tokens/access' }); var AccessTokenCollection = Backbone.Collection.extend({ idAttribute: 'id', model: AccessTokenModel, url: 'api/tokens/access' }); var AccessTokenView = Backbone.View.extend({ tagName: 'tr', initialize:function () { if (!this.template) { this.template = _.template($('#tmpl-access-token').html()); } if (!this.scopeTemplate) { this.scopeTemplate = _.template($('#tmpl-scope-list').html()); } if (!this.moreInfoTemplate) { this.moreInfoTemplate = _.template($('#tmpl-client-more-info-block').html()); } this.model.bind('change', this.render, this); }, events: { 'click .btn-delete':'deleteToken', 'click .token-substring':'showTokenValue', 'click .toggleMoreInformation': 'toggleMoreInformation' }, render:function (eventName) { var expirationDate = this.model.get("expiration"); if (expirationDate == null) { expirationDate = "Never"; } else if (!moment(expirationDate).isValid()) { expirationDate = "Unknown"; } else { expirationDate = moment(expirationDate).calendar(); } var json = {token: this.model.toJSON(), client: this.options.client.toJSON(), formattedExpiration: expirationDate}; this.$el.html(this.template(json)); // hide full value $('.token-full', this.el).hide(); // show scopes $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList})); $('.client-more-info-block', this.el).html(this.moreInfoTemplate({client: this.options.client.toJSON()})); return this; }, deleteToken:function (e) { e.preventDefault(); if (confirm("Are you sure sure you would like to revoke this token?")) { 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 // refresh the table in case we removed an id token, too app.tokensListView.refreshTable(); }); }); }, error:function (error, response) { //Pull out the response text. var responseJson = JSON.parse(response.responseText); //Display an alert with an error message $('#modalAlert div.modal-body').html(responseJson.errorMessage); $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog "backdrop" : "static", "keyboard" : true, "show" : true // ensure the modal is shown immediately }); } }); app.tokensListView.delegateEvents(); } return false; }, toggleMoreInformation:function(e) { e.preventDefault(); if ($('.moreInformation', this.el).is(':visible')) { // hide it $('.moreInformation', this.el).hide('fast'); $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-right'); $('.moreInformationContainer', this.el).removeClass('alert').removeClass('alert-info').addClass('muted'); } else { // show it $('.moreInformation', this.el).show('fast'); $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-down'); $('.moreInformationContainer', this.el).addClass('alert').addClass('alert-info').removeClass('muted'); } }, close:function () { $(this.el).unbind(); $(this.el).empty(); }, showTokenValue:function (e) { e.preventDefault(); $('.token-substring', this.el).hide(); $('.token-full', this.el).show(); } }); var RefreshTokenModel = Backbone.Model.extend({ idAttribute: 'id', defaults:{ id:null, value:null, scopes:[], clientId:null, userId:null, expiration:null }, urlRoot: 'api/tokens/refresh' }); var RefreshTokenCollection = Backbone.Collection.extend({ idAttribute: 'id', model: RefreshTokenModel, url: 'api/tokens/refresh' }); var RefreshTokenView = Backbone.View.extend({ tagName: 'tr', initialize:function () { if (!this.template) { this.template = _.template($('#tmpl-refresh-token').html()); } if (!this.scopeTemplate) { this.scopeTemplate = _.template($('#tmpl-scope-list').html()); } if (!this.moreInfoTemplate) { this.moreInfoTemplate = _.template($('#tmpl-client-more-info-block').html()); } this.model.bind('change', this.render, this); }, events: { 'click .btn-delete':'deleteToken', 'click .token-substring':'showTokenValue', 'click .toggleMoreInformation': 'toggleMoreInformation' }, render:function (eventName) { var expirationDate = this.model.get("expiration"); if (expirationDate == null) { expirationDate = "Never"; } else if (!moment(expirationDate).isValid()) { expirationDate = "Unknown"; } else { expirationDate = moment(expirationDate).calendar(); } var json = {token: this.model.toJSON(), client: this.options.client.toJSON(), formattedExpiration: expirationDate}; this.$el.html(this.template(json)); // hide full value $('.token-full', this.el).hide(); // show scopes $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList})); $('.client-more-info-block', this.el).html(this.moreInfoTemplate({client: this.options.client.toJSON()})); return this; }, deleteToken:function (e) { e.preventDefault(); if (confirm("Are you sure sure you would like to revoke this refresh token and its associated access tokens?")) { 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 // refresh the table in case the access tokens have changed, too app.tokensListView.refreshTable(); }); }); }, error:function (error, response) { //Pull out the response text. var responseJson = JSON.parse(response.responseText); //Display an alert with an error message $('#modalAlert div.modal-body').html(responseJson.errorMessage); $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog "backdrop" : "static", "keyboard" : true, "show" : true // ensure the modal is shown immediately }); } }); app.tokensListView.delegateEvents(); } return false; }, toggleMoreInformation:function(e) { e.preventDefault(); if ($('.moreInformation', this.el).is(':visible')) { // hide it $('.moreInformation', this.el).hide('fast'); $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-right'); } else { // show it $('.moreInformation', this.el).show('fast'); $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-down'); } }, close:function () { $(this.el).unbind(); $(this.el).empty(); }, showTokenValue:function (e) { e.preventDefault(); $('.token-substring', this.el).hide(); $('.token-full', this.el).show(); } }); var TokenListView = Backbone.View.extend({ tagName: 'span', events:{ "click .refresh-table":"refreshTable" }, load:function(callback) { if (this.model.access.isFetched && this.model.refresh.isFetched && this.options.clientList.isFetched && this.options.systemScopeList.isFetched) { callback(); return; } $('#loadingbox').sheet('show'); $('#loading').html('Access Tokens ' + 'Refresh Tokens ' + 'Clients ' + 'Scopes ' ); $.when(this.model.access.fetchIfNeeded({success:function(e) {$('#loading-access').addClass('label-success');}}), this.model.refresh.fetchIfNeeded({success:function(e) {$('#loading-refresh').addClass('label-success');}}), this.options.clientList.fetchIfNeeded({success:function(e) {$('#loading-clients').addClass('label-success');}}), this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}})) .done(function() { $('#loadingbox').sheet('hide'); callback(); }); }, refreshTable:function(e) { e.preventDefault(); $('#loadingbox').sheet('show'); $('#loading').html('Access Tokens ' + 'Refresh Tokens ' + 'Clients ' + 'Scopes ' ); var _self = this; $.when(this.model.access.fetch({success:function(e) {$('#loading-access').addClass('label-success');}}), this.model.refresh.fetch({success:function(e) {$('#loading-refresh').addClass('label-success');}}), this.options.clientList.fetch({success:function(e) {$('#loading-clients').addClass('label-success');}}), this.options.systemScopeList.fetch({success:function(e) {$('#loading-scopes').addClass('label-success');}})) .done(function(){ _self.render(); $('#loadingbox').sheet('hide'); }); }, togglePlaceholder:function() { if (this.model.access.length > 0) { $('#access-token-table', this.el).show(); $('#access-token-table-empty', this.el).hide(); } else { $('#access-token-table', this.el).hide(); $('#access-token-table-empty', this.el).show(); } if (this.model.refresh.length > 0) { $('#refresh-token-table', this.el).show(); $('#refresh-token-table-empty', this.el).hide(); } else { $('#refresh-token-table', this.el).hide(); $('#refresh-token-table-empty', this.el).show(); } }, render: function (eventName) { // append and render the table structure $(this.el).html($('#tmpl-token-table').html()); var _self = this; _.each(this.model.access.models, function (token) { // look up client var client = _self.options.clientList.getByClientId(token.get('clientId')); $('#access-token-table', _self.el).append(new AccessTokenView({model: token, client: client, systemScopeList: _self.options.systemScopeList}).render().el); }); _.each(this.model.refresh.models, function (token) { // look up client var client = _self.options.clientList.getByClientId(token.get('clientId')); $('#refresh-token-table', _self.el).append(new RefreshTokenView({model: token, client: client, systemScopeList: _self.options.systemScopeList}).render().el); }); /* _.each(this.model.models, function (scope) { $("#scope-table", this.el).append(new SystemScopeView({model: scope}).render().el); }, this); */ this.togglePlaceholder(); return this; } });