diff options
Diffstat (limited to 'base')
6 files changed, 184 insertions, 41 deletions
diff --git a/base/common/src/com/netscape/certsrv/user/UserData.java b/base/common/src/com/netscape/certsrv/user/UserData.java index da771f2e7..8fc0eab97 100644 --- a/base/common/src/com/netscape/certsrv/user/UserData.java +++ b/base/common/src/com/netscape/certsrv/user/UserData.java @@ -60,6 +60,7 @@ public class UserData { } String id; + String userID; String fullName; String email; String password; @@ -90,6 +91,15 @@ public class UserData { this.id = id; } + @XmlElement(name="UserID") + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } + @FormParam(Constants.PR_USER_FULLNAME) @XmlElement(name="FullName") public String getFullName() { @@ -167,10 +177,12 @@ public class UserData { result = prime * result + ((email == null) ? 0 : email.hashCode()); result = prime * result + ((fullName == null) ? 0 : fullName.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((link == null) ? 0 : link.hashCode()); result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((phone == null) ? 0 : phone.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((userID == null) ? 0 : userID.hashCode()); return result; } @@ -203,6 +215,11 @@ public class UserData { return false; } else if (!id.equals(other.id)) return false; + if (link == null) { + if (other.link != null) + return false; + } else if (!link.equals(other.link)) + return false; if (password == null) { if (other.password != null) return false; @@ -223,6 +240,11 @@ public class UserData { return false; } else if (!type.equals(other.type)) return false; + if (userID == null) { + if (other.userID != null) + return false; + } else if (!userID.equals(other.userID)) + return false; return true; } diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserAddCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserAddCLI.java index 33a6786e7..5e22522c8 100644 --- a/base/java-tools/src/com/netscape/cmstools/user/UserAddCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/user/UserAddCLI.java @@ -86,10 +86,10 @@ public class UserAddCLI extends CLI { System.exit(1); } - String userId = cmdArgs[0]; + String userID = cmdArgs[0]; UserData userData = new UserData(); - userData.setID(userId); + userData.setUserID(userID); userData.setFullName(cmd.getOptionValue("fullName")); userData.setEmail(cmd.getOptionValue("email")); userData.setPassword(cmd.getOptionValue("password")); @@ -99,7 +99,7 @@ public class UserAddCLI extends CLI { userData = userCLI.userClient.addUser(userData); - MainCLI.printMessage("Added user \"" + userId + "\""); + MainCLI.printMessage("Added user \"" + userID + "\""); UserCLI.printUser(userData); } diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java b/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java index 63a461355..265fe3e1b 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java +++ b/base/server/cms/src/com/netscape/cms/servlet/admin/UserService.java @@ -108,14 +108,17 @@ public class UserService extends PKIService implements UserResource { UserData userData = new UserData(); - String id = user.getUserID(); - if (!StringUtils.isEmpty(id)) userData.setID(id); + String userID = user.getUserID(); + if (!StringUtils.isEmpty(userID)) { + userData.setID(userID); + userData.setUserID(userID); + } String fullName = user.getFullName(); if (!StringUtils.isEmpty(fullName)) userData.setFullName(fullName); - String userID = URLEncoder.encode(id, "UTF-8"); - URI uri = uriInfo.getBaseUriBuilder().path(UserResource.class).path("{userID}").build(userID); + String encodedUserID = URLEncoder.encode(userID, "UTF-8"); + URI uri = uriInfo.getBaseUriBuilder().path(UserResource.class).path("{userID}").build(encodedUserID); userData.setLink(new Link("self", uri)); return userData; @@ -256,10 +259,13 @@ public class UserService extends PKIService implements UserResource { @Override public Response addUser(UserData userData) { + CMS.debug("UserService.addUser()"); + if (userData == null) throw new BadRequestException("User data is null."); IConfigStore cs = CMS.getConfigStore(); - String userID = userData.getID(); + String userID = userData.getUserID(); + CMS.debug("User ID: " + userID); // ensure that any low-level exceptions are reported // to the signed audit log and stored as failures @@ -284,6 +290,7 @@ public class UserService extends PKIService implements UserResource { IUser user = userGroupManager.createUser(userID); String fname = userData.getFullName(); + CMS.debug("Full name: " + fname); if (fname == null || fname.length() == 0) { String msg = getUserMessage("CMS_USRGRP_USER_ADD_FAILED_1", headers, "full name"); @@ -295,6 +302,7 @@ public class UserService extends PKIService implements UserResource { } String email = userData.getEmail(); + CMS.debug("Email: " + email); if (email != null) { user.setEmail(email); } else { @@ -302,6 +310,7 @@ public class UserService extends PKIService implements UserResource { } String pword = userData.getPassword(); + CMS.debug("Password: " + (pword == null ? null : "********")); if (pword != null && !pword.equals("")) { IPasswordCheck passwdCheck = CMS.getPasswordChecker(); @@ -315,6 +324,7 @@ public class UserService extends PKIService implements UserResource { } String phone = userData.getPhone(); + CMS.debug("Phone: " + phone); if (phone != null) { user.setPhone(phone); } else { @@ -322,6 +332,7 @@ public class UserService extends PKIService implements UserResource { } String type = userData.getType(); + CMS.debug("Type: " + type); if (type != null) { user.setUserType(type); } else { @@ -329,11 +340,13 @@ public class UserService extends PKIService implements UserResource { } String state = userData.getState(); + CMS.debug("State: " + state); if (state != null) { user.setState(state); } String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES); + CMS.debug("TPS profiles: " + tpsProfiles); String csType = cs.getString("cs.type"); if (tpsProfiles != null) { if (!csType.equals("TPS")) { diff --git a/base/server/share/webapps/pki/js/pki-ui.js b/base/server/share/webapps/pki/js/pki-ui.js index 7fbb8341a..0ac313952 100644 --- a/base/server/share/webapps/pki/js/pki-ui.js +++ b/base/server/share/webapps/pki/js/pki-ui.js @@ -32,7 +32,11 @@ var Model = Backbone.Model.extend({ save: function(attributes, options) { var self = this; if (attributes == undefined) attributes = self.attributes; + // convert attributes into JSON request var request = self.createRequest(attributes); + // remove old attributes + if (self.isNew()) self.clear(); + // send JSON request Model.__super__.save.call(self, request, options); } }); @@ -137,15 +141,14 @@ var Dialog = Backbone.View.extend({ e.preventDefault(); }); + // set/unset readonly fields $("input", self.$el).each(function(index) { var input = $(this); - - self.loadField(input); - - // mark some fields readonly var name = input.attr("name"); if ( _.contains(self.readonly, name)) { input.attr("readonly", "readonly"); + } else { + input.removeAttr("readonly"); } }); @@ -155,6 +158,7 @@ var Dialog = Backbone.View.extend({ if (_.contains(self.actions, action)) { // enable buttons for specified actions + button.show(); button.click(function(e) { self.performAction(action); e.preventDefault(); @@ -164,12 +168,30 @@ var Dialog = Backbone.View.extend({ button.hide(); } }); + + self.loadFields(); + // save the fields back into model so the model + // can detect which fields are changed + self.saveFields(); }, performAction: function(action) { var self = this; - if (action == "save") { - // save changes + if (action == "add") { + self.add({ + success: function(model, response, options) { + self.close(); + }, + error: function(model, response, options) { + if (response.status == 201) { + self.close(); + return; + } + alert("ERROR: " + response.responseText); + } + }); + + } else if (action == "save") { self.save({ success: function(model, response, options) { self.close(); @@ -189,8 +211,27 @@ var Dialog = Backbone.View.extend({ }, open: function() { var self = this; + if (self.model.isNew()) { + self.render(); + self.$el.show(); + } else { + self.load(); + } + }, + close: function() { + var self = this; + self.$el.hide(); - // load data + // remove event handlers + self.$(".rcue-button-close").off("click"); + self.$("button").each(function(index) { + var button = $(this); + button.off("click"); + }); + self.trigger("close"); + }, + load: function() { + var self = this; self.model.fetch({ success: function(model, response, options) { self.render(); @@ -201,29 +242,45 @@ var Dialog = Backbone.View.extend({ } }); }, - close: function() { - this.$el.hide(); + loadFields: function() { + var self = this; + + $("input", self.$el).each(function(index) { + var input = $(this); + self.loadField(input); + }); }, loadField: function(input) { var self = this; var name = input.attr("name"); var value = self.model.get(name); + if (!value) value = ""; input.val(value); }, - save: function(options) { + add: function(options) { var self = this; - var attributes = {}; - $("input", self.$el).each(function(index) { - var input = $(this); - self.saveField(input, attributes); + self.saveFields(); + + var changedAttributes = self.model.changedAttributes(); + if (!changedAttributes) return; + + // save non-empty attributes with POST + self.model.save(changedAttributes, { + wait: true, + success: options.success, + error: options.error }); - self.model.set(attributes); + }, + save: function(options) { + var self = this; + + self.saveFields(); var changedAttributes = self.model.changedAttributes(); if (!changedAttributes) return; - // save changed attributes only + // save changed attributes with PATCH self.model.save(changedAttributes, { patch: true, wait: true, @@ -231,6 +288,16 @@ var Dialog = Backbone.View.extend({ error: options.error }); }, + saveFields: function() { + var self = this; + + var attributes = {}; + $("input", self.$el).each(function(index) { + var input = $(this); + self.saveField(input, attributes); + }); + self.model.set(attributes); + }, saveField: function(input, attributes) { var self = this; var name = input.attr("name"); @@ -252,7 +319,8 @@ var TableItemView = Backbone.View.extend({ var name = item.attr("name"); var value = self.model.get(name); - if (name == "id") { + if (index == 0) { + // link first cell to edit dialog item.empty(); $("<a/>", { href: "#", @@ -264,8 +332,11 @@ var TableItemView = Backbone.View.extend({ e.preventDefault(); } }).appendTo(item); + } else { + // show cell content in plain text item.text(value); + // update cell automatically on model change self.model.on("change:" + name, function(event) { item.text(self.model.get(name)); }); @@ -279,13 +350,25 @@ var TableView = Backbone.View.extend({ var self = this; TableView.__super__.initialize.call(self, options); + self.addDialog = options.addDialog; self.editDialog = options.editDialog; - self.tbody = $("tbody", self.el); + self.thead = $("thead", self.$el); + $("button[name=add]", self.thead).click(function(e) { + var dialog = self.addDialog; + dialog.model = new self.collection.model(); + dialog.on("close", function(event) { + self.render(); + }); + dialog.open(); + e.preventDefault(); + }); + + self.tbody = $("tbody", self.$el); self.template = $("tr", self.tbody).detach(); // attach link handlers - self.tfoot = $("tfoot", self.el); + self.tfoot = $("tfoot", self.$el); $("a.prev", self.tfoot).click(function(e) { if (self.collection.link("prev") == undefined) return; self.collection.go("prev"); diff --git a/base/tps-tomcat/shared/webapps/tps/js/user.js b/base/tps-tomcat/shared/webapps/tps/js/user.js index 9f36eb481..670780c40 100644 --- a/base/tps-tomcat/shared/webapps/tps/js/user.js +++ b/base/tps-tomcat/shared/webapps/tps/js/user.js @@ -22,18 +22,24 @@ var UserModel = Model.extend({ urlRoot: "/tps/rest/admin/users", parseResponse: function(response) { - var attributes = response.User.Attributes.Attribute; - attributes = attributes == undefined ? [] : [].concat(attributes); + + if (!response || !response.User) return {}; var attrs = {}; - _(attributes).each(function(attribute) { - var name = attribute["@name"]; - var value = attribute["$"]; - attrs[name] = value; - }); + if (response.User.Attributes) { + var attributes = response.User.Attributes.Attribute; + attributes = attributes == undefined ? [] : [].concat(attributes); + + _(attributes).each(function(attribute) { + var name = attribute["@name"]; + var value = attribute["$"]; + attrs[name] = value; + }); + } return { id: response.User["@id"], + userID: response.User.UserID, fullName: response.User.FullName, email: response.User.Email, state: response.User.State, @@ -54,7 +60,8 @@ var UserModel = Model.extend({ return { User: { - "@id": attributes.id, + "@id": this.id, + UserID: attributes.userID, FullName: attributes.fullName, Email: attributes.email, State: attributes.state, @@ -66,6 +73,7 @@ var UserModel = Model.extend({ }); var UserCollection = Collection.extend({ + model: UserModel, urlRoot: "/tps/rest/admin/users", getEntries: function(response) { return response.Users.User; @@ -76,6 +84,7 @@ var UserCollection = Collection.extend({ parseEntry: function(entry) { return new UserModel({ id: entry["@id"], + userID: entry.UserID, fullName: entry.FullName }); } @@ -92,8 +101,10 @@ var UserDialog = Dialog.extend({ } var attributes = self.model.get("attributes"); - var value = attributes.tpsProfiles; - input.val(value); + if (attributes) { + var value = attributes.tpsProfiles; + input.val(value); + } }, saveField: function(input, attributes) { var self = this; diff --git a/base/tps-tomcat/shared/webapps/tps/users.html b/base/tps-tomcat/shared/webapps/tps/users.html index fdf7e7418..0c95ad7ce 100644 --- a/base/tps-tomcat/shared/webapps/tps/users.html +++ b/base/tps-tomcat/shared/webapps/tps/users.html @@ -25,15 +25,24 @@ <script src="/tps/js/user.js"></script> <script> $(function() { + var addDialog = new UserDialog({ + el: $("#user-dialog"), + title: "Add User", + readonly: ["type"], + actions: ["cancel", "add"] + }); + var editDialog = new UserDialog({ el: $("#user-dialog"), title: "Edit User", - readonly: ["id", "type"] + readonly: ["userID", "type"], + actions: ["cancel", "save"] }); new TableView({ el: $("table[name='users']"), collection: new UserCollection({ size: 3 }), + addDialog: addDialog, editDialog: editDialog }); }); @@ -48,7 +57,10 @@ $(function() { <tr> <th class="rcue-table-actions" colspan="2"> <span><input type="text" placeholder="Search..."></span> - <span><button>Add</button><button>Remove</button></span> + <span> + <button name="add">Add</button> + <button name="remove">Remove</button> + </span> </th> </tr> <tr> @@ -58,7 +70,7 @@ $(function() { </thead> <tbody> <tr> - <td name="id"> </td> + <td name="userID"> </td> <td name="fullName"> </td> </tr> </tbody> @@ -81,7 +93,7 @@ $(function() { <a class="rcue-button-close" href="#"></a> </header> <fieldset> - <label>User ID</label><input name="id" type="text"><br> + <label>User ID</label><input name="userID" type="text"><br> <label>Full Name</label><input name="fullName" type="text"><br> <label>Email</label><input name="email" type="text"><br> <label>Type</label><input name="type" type="text"><br> @@ -89,7 +101,9 @@ $(function() { <label>TPS Profiles</label><input name="tpsProfiles" type="text"><br> </fieldset> <footer> + <button name="add" class="primary">Add</button> <button name="save" class="primary">Save</button> + <button name="remove" class="primary">Remove</button> <button name="cancel">Cancel</button> </footer> </div> |