From 23ded765e684d8377a75b0cc36af85fdb0a6c63f Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Fri, 10 Apr 2015 22:51:22 -0400 Subject: [PATCH] Fixed action links in TPS UI. The TPS UI has been modified to display the appropriate action links based on the roles of the user. TPS agent can only enable and disable profiles, and also approve or reject pending requests. TPS admin can only edit disabled profiles, then submit it for approval, or cancel the request. The action links have been updated to display in a more consistent way. https://fedorahosted.org/pki/ticket/1292 --- base/server/share/webapps/pki/js/pki-ui.js | 10 +- base/tps/shared/webapps/tps/js/account.js | 30 ++++-- base/tps/shared/webapps/tps/js/audit.js | 12 ++- base/tps/shared/webapps/tps/js/authenticator.js | 17 +--- base/tps/shared/webapps/tps/js/config.js | 58 ++++++++++- base/tps/shared/webapps/tps/js/connector.js | 17 +--- base/tps/shared/webapps/tps/js/profile-mapping.js | 17 +--- base/tps/shared/webapps/tps/js/profile.js | 102 ++++++++++++++++--- base/tps/shared/webapps/tps/js/token.js | 8 +- base/tps/shared/webapps/tps/js/tps.js | 109 +++++++++++++++++++-- base/tps/shared/webapps/tps/ui/audit.html | 9 +- base/tps/shared/webapps/tps/ui/authenticator.html | 13 ++- base/tps/shared/webapps/tps/ui/config.html | 6 +- base/tps/shared/webapps/tps/ui/connector.html | 13 ++- base/tps/shared/webapps/tps/ui/group.html | 6 +- base/tps/shared/webapps/tps/ui/index.html | 4 +- .../tps/shared/webapps/tps/ui/profile-mapping.html | 13 ++- base/tps/shared/webapps/tps/ui/profile.html | 13 ++- base/tps/shared/webapps/tps/ui/token.html | 10 +- base/tps/shared/webapps/tps/ui/user.html | 6 +- 20 files changed, 346 insertions(+), 127 deletions(-) diff --git a/base/server/share/webapps/pki/js/pki-ui.js b/base/server/share/webapps/pki/js/pki-ui.js index 7d8e6eef6c14ae1d913a191cc834d6a279e48333..e32567121585eb876d7b20e7d5cab0d22efac5c1 100644 --- a/base/server/share/webapps/pki/js/pki-ui.js +++ b/base/server/share/webapps/pki/js/pki-ui.js @@ -925,8 +925,8 @@ var EntryPage = Page.extend({ setup: function() { var self = this; - self.menu = self.$(".pki-menu"); - self.editLink = $("a[name='edit']", self.menu); + self.links = self.$(".pki-links"); + self.editLink = $("[name='edit']", self.links); self.buttons = self.$(".pki-buttons"); self.cancelButton = $("button[name='cancel']", self.buttons); @@ -935,7 +935,7 @@ var EntryPage = Page.extend({ self.idField = self.$("input[name='id']"); self.statusField = self.$("input[name='status']"); - self.editLink.click(function(e) { + $("a", self.editLink).click(function(e) { self.mode = "edit"; self.render(); e.preventDefault(); @@ -997,10 +997,10 @@ var EntryPage = Page.extend({ }); self.buttons.hide(); - self.menu.show(); + self.links.show(); } else { - self.menu.hide(); + self.links.hide(); // Show editable fields. self.$(".pki-fields input").each(function(index) { diff --git a/base/tps/shared/webapps/tps/js/account.js b/base/tps/shared/webapps/tps/js/account.js index 97b222aaa07b42056395ddb9baaec4d85381a252..8960ff731d1faec646dac0763a35aa2c40b3eb9a 100644 --- a/base/tps/shared/webapps/tps/js/account.js +++ b/base/tps/shared/webapps/tps/js/account.js @@ -24,14 +24,30 @@ function Account() { this.url = "/tps/rest/account"; this.login = function(options) { - var jqxhr = $.get(this.url + "/login", null, null, "json"); - jqxhr.done(options.success); - jqxhr.fail(options.error); + var self = this; + + $.ajax({ + type: "GET", + url: self.url + "/login", + dataType: "json" + }).done(function(data, textStatus, jqXHR) { + if (options.success) options.success.call(self, data, textStatus, jqXHR); + }).fail(function(jqXHR, textStatus, errorThrown) { + if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown); + }); }; this.logout = function(options) { - var jqxhr = $.get(this.url + "/logout"); - jqxhr.done(options.success); - jqxhr.fail(options.error); + var self = this; + + $.ajax({ + type: "GET", + url: self.url + "/logout", + dataType: "json" + }).done(function(data, textStatus, jqXHR) { + if (options.success) options.success.call(self, data, textStatus, jqXHR); + }).fail(function(jqXHR, textStatus, errorThrown) { + if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown); + }); }; -}; \ No newline at end of file +}; diff --git a/base/tps/shared/webapps/tps/js/audit.js b/base/tps/shared/webapps/tps/js/audit.js index 986596e1d0ddee440a5f87f5a6e2a14ff991f5f8..678ffd2c793ce50cc2dd8ff1045c053ce446886e 100644 --- a/base/tps/shared/webapps/tps/js/audit.js +++ b/base/tps/shared/webapps/tps/js/audit.js @@ -142,10 +142,10 @@ var AuditPage = EntryPage.extend({ AuditPage.__super__.setup.call(self); - self.enableLink = $("a[name='enable']", self.menu); - self.disableLink = $("a[name='disable']", self.menu); + self.enableLink = $("[name='enable']", self.links); + self.disableLink = $("[name='disable']", self.links); - self.enableLink.click(function(e) { + $("a", self.enableLink).click(function(e) { e.preventDefault(); @@ -166,7 +166,7 @@ var AuditPage = EntryPage.extend({ }); }); - self.disableLink.click(function(e) { + $("a", self.disableLink).click(function(e) { e.preventDefault(); @@ -204,10 +204,12 @@ var AuditPage = EntryPage.extend({ var status = self.entry.status; if (status == "Disabled") { + self.editLink.show(); self.enableLink.show(); self.disableLink.hide(); - } else if (status == "Enabled") { + } else { + self.editLink.hide(); self.enableLink.hide(); self.disableLink.show(); } diff --git a/base/tps/shared/webapps/tps/js/authenticator.js b/base/tps/shared/webapps/tps/js/authenticator.js index f91cf6bfeb3ad7046710cb227bf8c1a253b55926..b83838c67546e6f9c147d6a57bee3f80bc9f9769 100644 --- a/base/tps/shared/webapps/tps/js/authenticator.js +++ b/base/tps/shared/webapps/tps/js/authenticator.js @@ -38,24 +38,11 @@ var AuthenticatorModel = Model.extend({ } }; }, - enable: function(options) { + changeStatus: function(action, options) { var self = this; $.ajax({ type: "POST", - url: self.url() + "?action=enable", - dataType: "json" - }).done(function(data, textStatus, jqXHR) { - self.set(self.parseResponse(data)); - if (options.success) options.success.call(self, data, textStatus, jqXHR); - }).fail(function(jqXHR, textStatus, errorThrown) { - if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown); - }); - }, - disable: function(options) { - var self = this; - $.ajax({ - type: "POST", - url: self.url() + "?action=disable", + url: self.url() + "?action=" + action, dataType: "json" }).done(function(data, textStatus, jqXHR) { self.set(self.parseResponse(data)); diff --git a/base/tps/shared/webapps/tps/js/config.js b/base/tps/shared/webapps/tps/js/config.js index 5b651a09d40279eb9d73c9fdf321fea8c67955e4..d06f626d2fa650a3970158920c5b7964cc53f734 100644 --- a/base/tps/shared/webapps/tps/js/config.js +++ b/base/tps/shared/webapps/tps/js/config.js @@ -40,12 +40,64 @@ var ConfigModel = Model.extend({ } }); -var ConfigPage = ConfigEntryPage.extend({ +var ConfigPage = EntryPage.extend({ initialize: function(options) { var self = this; options.model = new ConfigModel(); - options.tableItem = PropertiesTableItem; - options.tableSize = 15; ConfigPage.__super__.initialize.call(self, options); + self.tableItem = options.tableItem || PropertiesTableItem; + self.tableSize = options.tableSize || 15; + }, + setup: function() { + var self = this; + + ConfigPage.__super__.setup.call(self); + + var dialog = self.$("#property-dialog"); + + var addDialog = new Dialog({ + el: dialog, + title: "Add Property", + actions: ["cancel", "add"] + }); + + var table = self.$("table[name='properties']"); + self.addButton = $("button[name='add']", table); + self.removeButton = $("button[name='remove']", table); + + self.propertiesTable = new PropertiesTable({ + el: table, + addDialog: addDialog, + tableItem: self.tableItem, + pageSize: self.tableSize, + parent: self + }); + }, + renderContent: function() { + var self = this; + + ConfigPage.__super__.renderContent.call(self); + + if (self.mode == "add") { + self.propertiesTable.mode = "edit"; + self.propertiesTable.entries = []; + + } else if (self.mode == "edit") { + self.propertiesTable.mode = "edit"; + self.propertiesTable.entries = self.entry.properties; + + } else { // self.mode == "view" + self.propertiesTable.mode = "view"; + self.propertiesTable.entries = self.entry.properties; + } + + self.propertiesTable.render(); + }, + saveFields: function() { + var self = this; + + ConfigPage.__super__.saveFields.call(self); + + self.entry.properties = self.propertiesTable.entries; } }); diff --git a/base/tps/shared/webapps/tps/js/connector.js b/base/tps/shared/webapps/tps/js/connector.js index bc7e4c2bd371f2b6fa210bea39302d7cd21aaaa8..1095ecd741cd1f2d44bab9f56c625a32f4be44f8 100644 --- a/base/tps/shared/webapps/tps/js/connector.js +++ b/base/tps/shared/webapps/tps/js/connector.js @@ -38,24 +38,11 @@ var ConnectorModel = Model.extend({ } }; }, - enable: function(options) { + changeStatus: function(action, options) { var self = this; $.ajax({ type: "POST", - url: self.url() + "?action=enable", - dataType: "json" - }).done(function(data, textStatus, jqXHR) { - self.set(self.parseResponse(data)); - if (options.success) options.success.call(self, data, textStatus, jqXHR); - }).fail(function(jqXHR, textStatus, errorThrown) { - if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown); - }); - }, - disable: function(options) { - var self = this; - $.ajax({ - type: "POST", - url: self.url() + "?action=disable", + url: self.url() + "?action=" + action, dataType: "json" }).done(function(data, textStatus, jqXHR) { self.set(self.parseResponse(data)); diff --git a/base/tps/shared/webapps/tps/js/profile-mapping.js b/base/tps/shared/webapps/tps/js/profile-mapping.js index 54c04256279b5e4fcb92e12cb5cb202644aa62f8..8df3b393ff149c5d51799e632a9cae95e3386146 100644 --- a/base/tps/shared/webapps/tps/js/profile-mapping.js +++ b/base/tps/shared/webapps/tps/js/profile-mapping.js @@ -38,24 +38,11 @@ var ProfileMappingModel = Model.extend({ } }; }, - enable: function(options) { + changeStatus: function(action, options) { var self = this; $.ajax({ type: "POST", - url: self.url() + "?action=enable", - dataType: "json" - }).done(function(data, textStatus, jqXHR) { - self.set(self.parseResponse(data)); - if (options.success) options.success.call(self, data, textStatus, jqXHR); - }).fail(function(jqXHR, textStatus, errorThrown) { - if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown); - }); - }, - disable: function(options) { - var self = this; - $.ajax({ - type: "POST", - url: self.url() + "?action=disable", + url: self.url() + "?action=" + action, dataType: "json" }).done(function(data, textStatus, jqXHR) { self.set(self.parseResponse(data)); diff --git a/base/tps/shared/webapps/tps/js/profile.js b/base/tps/shared/webapps/tps/js/profile.js index 0454686a9993560909cd4d350488a2ac823fc769..a795b29fc184b6b62a2bee5e0956c0c963a5ceb8 100644 --- a/base/tps/shared/webapps/tps/js/profile.js +++ b/base/tps/shared/webapps/tps/js/profile.js @@ -38,24 +38,11 @@ var ProfileModel = Model.extend({ } }; }, - enable: function(options) { + changeStatus: function(action, options) { var self = this; $.ajax({ type: "POST", - url: self.url() + "?action=enable", - dataType: "json" - }).done(function(data, textStatus, jqXHR) { - self.set(self.parseResponse(data)); - if (options.success) options.success.call(self, data, textStatus, jqXHR); - }).fail(function(jqXHR, textStatus, errorThrown) { - if (options.error) options.error.call(self, jqXHR, textStatus, errorThrown); - }); - }, - disable: function(options) { - var self = this; - $.ajax({ - type: "POST", - url: self.url() + "?action=disable", + url: self.url() + "?action=" + action, dataType: "json" }).done(function(data, textStatus, jqXHR) { self.set(self.parseResponse(data)); @@ -94,6 +81,91 @@ var ProfilesTable = ModelTable.extend({ } }); +var ProfilePage = ConfigEntryPage.extend({ + renderContent: function() { + var self = this; + + ProfilePage.__super__.renderContent.call(self); + + var roles = tps.user.Roles.Role; + var status = self.entry.status; + + if (_.contains(roles, "Administrators")) { + + // admins can edit disabled entries + if (status == "Disabled") { + self.editLink.show(); + } else { + self.editLink.hide(); + } + + } else { + self.editLink.hide(); + } + + if (_.contains(roles, "TPS Agents")) { + + // agents can enable or disable entries + if (status == "Disabled") { + self.approveLink.hide(); + self.rejectLink.hide(); + self.enableLink.show(); + self.disableLink.hide(); + + } else if (status == "Enabled") { + self.approveLink.hide(); + self.rejectLink.hide(); + self.enableLink.hide(); + self.disableLink.show(); + + } else if (status == "Pending_Approval") { + self.approveLink.show(); + self.rejectLink.show(); + self.enableLink.hide(); + self.disableLink.hide(); + + } else { + self.approveLink.hide(); + self.rejectLink.hide(); + self.enableLink.hide(); + self.disableLink.hide(); + } + + self.submitLink.hide(); + self.cancelLink.hide(); + + } else if (_.contains(roles, "Administrators")) { + + // admins can submit or cancel entries + if (status == "Disabled") { + self.submitLink.show(); + self.cancelLink.hide(); + + } else if (status == "Pending_Approval") { + self.submitLink.hide(); + self.cancelLink.show(); + + } else { + self.submitLink.hide(); + self.cancelLink.hide(); + } + + self.approveLink.hide(); + self.rejectLink.hide(); + self.enableLink.hide(); + self.disableLink.hide(); + + } else { + self.enableLink.hide(); + self.disableLink.hide(); + self.approveLink.hide(); + self.rejectLink.hide(); + self.submitLink.hide(); + self.cancelLink.hide(); + } + } +}); + var ProfilesPage = Page.extend({ load: function() { var self = this; diff --git a/base/tps/shared/webapps/tps/js/token.js b/base/tps/shared/webapps/tps/js/token.js index c1f27b13248b4072fbd4f61072c28ed3c7505a8f..78a3f6a8db750f4f0f08ae933d59cd3c02e02ddd 100644 --- a/base/tps/shared/webapps/tps/js/token.js +++ b/base/tps/shared/webapps/tps/js/token.js @@ -110,9 +110,9 @@ var TokenPage = EntryPage.extend({ TokenPage.__super__.setup.call(self); - self.changeStatusLink = $("a[name='changeStatus']", self.menu); + self.changeStatusLink = $("[name='changeStatus']", self.links); - self.changeStatusLink.click(function(e) { + $("a", self.changeStatusLink).click(function(e) { e.preventDefault(); @@ -154,9 +154,9 @@ var TokenPage = EntryPage.extend({ dialog.open(); }); - self.showCertsLink = $("a[name='showCerts']", self.menu); + self.showCertsLink = $("[name='showCerts']", self.links); - self.showCertsLink.click(function(e) { + $("a", self.showCertsLink).click(function(e) { e.preventDefault(); window.location.hash = window.location.hash + "/certs"; diff --git a/base/tps/shared/webapps/tps/js/tps.js b/base/tps/shared/webapps/tps/js/tps.js index 30fade968a9adf79b4449cf4c959a2ba9bad8747..ee5a85caea0d49ce9051eaf20441b48faabfd79d 100644 --- a/base/tps/shared/webapps/tps/js/tps.js +++ b/base/tps/shared/webapps/tps/js/tps.js @@ -146,16 +146,104 @@ var ConfigEntryPage = EntryPage.extend({ ConfigEntryPage.__super__.setup.call(self); - self.enableLink = $("a[name='enable']", self.menu); - self.disableLink = $("a[name='disable']", self.menu); + self.submitLink = $("[name='submit']", self.links); + self.cancelLink = $("[name='cancel']", self.links); + self.approveLink = $("[name='approve']", self.links); + self.rejectLink = $("[name='reject']", self.links); + self.enableLink = $("[name='enable']", self.links); + self.disableLink = $("[name='disable']", self.links); - self.enableLink.click(function(e) { + $("a", self.submitLink).click(function(e) { + + e.preventDefault(); + + var message = "Are you sure you want to submit this entry?"; + if (!confirm(message)) return; + self.model.changeStatus("submit", { + success: function(data, textStatus, jqXHR) { + self.entry = _.clone(self.model.attributes); + self.render(); + }, + error: function(jqXHR, textStatus, errorThrown) { + new ErrorDialog({ + el: $("#error-dialog"), + title: "HTTP Error " + jqXHR.responseJSON.Code, + content: jqXHR.responseJSON.Message + }).open(); + } + }); + }); + + $("a", self.cancelLink).click(function(e) { + + e.preventDefault(); + + var message = "Are you sure you want to cancel this entry?"; + if (!confirm(message)) return; + self.model.changeStatus("cancel", { + success: function(data, textStatus, jqXHR) { + self.entry = _.clone(self.model.attributes); + self.render(); + }, + error: function(jqXHR, textStatus, errorThrown) { + new ErrorDialog({ + el: $("#error-dialog"), + title: "HTTP Error " + jqXHR.responseJSON.Code, + content: jqXHR.responseJSON.Message + }).open(); + } + }); + }); + + $("a", self.approveLink).click(function(e) { + + e.preventDefault(); + + var message = "Are you sure you want to approve this entry?"; + if (!confirm(message)) return; + self.model.changeStatus("approve", { + success: function(data, textStatus, jqXHR) { + self.entry = _.clone(self.model.attributes); + self.render(); + }, + error: function(jqXHR, textStatus, errorThrown) { + new ErrorDialog({ + el: $("#error-dialog"), + title: "HTTP Error " + jqXHR.responseJSON.Code, + content: jqXHR.responseJSON.Message + }).open(); + } + }); + }); + + $("a", self.rejectLink).click(function(e) { + + e.preventDefault(); + + var message = "Are you sure you want to reject this entry?"; + if (!confirm(message)) return; + self.model.changeStatus("reject", { + success: function(data, textStatus, jqXHR) { + self.entry = _.clone(self.model.attributes); + self.render(); + }, + error: function(jqXHR, textStatus, errorThrown) { + new ErrorDialog({ + el: $("#error-dialog"), + title: "HTTP Error " + jqXHR.responseJSON.Code, + content: jqXHR.responseJSON.Message + }).open(); + } + }); + }); + + $("a", self.enableLink).click(function(e) { e.preventDefault(); var message = "Are you sure you want to enable this entry?"; if (!confirm(message)) return; - self.model.enable({ + self.model.changeStatus("enable", { success: function(data, textStatus, jqXHR) { self.entry = _.clone(self.model.attributes); self.render(); @@ -170,13 +258,13 @@ var ConfigEntryPage = EntryPage.extend({ }); }); - self.disableLink.click(function(e) { + $("a", self.disableLink).click(function(e) { e.preventDefault(); var message = "Are you sure you want to disable this entry?"; if (!confirm(message)) return; - self.model.disable({ + self.model.changeStatus("disable", { success: function(data, textStatus, jqXHR) { self.entry = _.clone(self.model.attributes); self.render(); @@ -218,14 +306,21 @@ var ConfigEntryPage = EntryPage.extend({ var status = self.entry.status; if (status == "Disabled") { + self.editLink.show(); self.enableLink.show(); self.disableLink.hide(); - } else if (status == "Enabled") { + } else { + self.editLink.hide(); self.enableLink.hide(); self.disableLink.show(); } + self.submitLink.hide(); + self.cancelLink.hide(); + self.approveLink.hide(); + self.rejectLink.hide(); + if (self.mode == "add") { self.propertiesTable.mode = "edit"; self.propertiesTable.entries = []; diff --git a/base/tps/shared/webapps/tps/ui/audit.html b/base/tps/shared/webapps/tps/ui/audit.html index 3e6cc6cbbc8cb402b128cbef67559073b664b775..1f9c0c14d7bdc7060522c5f716e86bf9b751162e 100644 --- a/base/tps/shared/webapps/tps/ui/audit.html +++ b/base/tps/shared/webapps/tps/ui/audit.html @@ -25,10 +25,11 @@ - +