From edewata at redhat.com Mon Jan 4 20:31:28 2016 From: edewata at redhat.com (Endi Sukma Dewata) Date: Mon, 4 Jan 2016 14:31:28 -0600 Subject: [Pki-devel] [PATCH] 665 Added table to manage TPS user profiles. Message-ID: <568AD6A0.1090606@redhat.com> The TPS UI has been modified to provide a table as an interface to manage the user profiles. When adding a profile, the profile can be selected from a list of available profiles. The UserService and UGSubsystem have been modified to allow adding a user with no assigned profiles. https://fedorahosted.org/pki/ticket/1478 -- Endi S. Dewata -------------- next part -------------- From 31972666380c97fc29f3095cfe7eb026b2e6e81d Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 24 Dec 2015 17:20:58 +0100 Subject: [PATCH] Added table to manage TPS user profiles. The TPS UI has been modified to provide a table as an interface to manage the user profiles. When adding a profile, the profile can be selected from a list of available profiles. The UserService and UGSubsystem have been modified to allow adding a user with no assigned profiles. https://fedorahosted.org/pki/ticket/1478 --- .../src/org/dogtagpki/server/rest/UserService.java | 97 +++++++--- .../com/netscape/cmscore/usrgrp/UGSubsystem.java | 86 ++++----- base/server/share/webapps/pki/js/pki-ui.js | 8 +- base/tps/shared/webapps/tps/js/user.js | 196 +++++++++++++++++++-- base/tps/shared/webapps/tps/ui/user.html | 78 +++++++- 5 files changed, 358 insertions(+), 107 deletions(-) diff --git a/base/server/cms/src/org/dogtagpki/server/rest/UserService.java b/base/server/cms/src/org/dogtagpki/server/rest/UserService.java index 53ecc2b9e778db3bf6e14bc05989446d4a741223..3de7384ee0dc8789e74b619191e7e4c4e739ae6f 100644 --- a/base/server/cms/src/org/dogtagpki/server/rest/UserService.java +++ b/base/server/cms/src/org/dogtagpki/server/rest/UserService.java @@ -39,9 +39,6 @@ import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import netscape.security.pkcs.PKCS7; -import netscape.security.x509.X509CertImpl; - import org.apache.commons.lang.StringUtils; import org.jboss.resteasy.plugins.providers.atom.Link; import org.mozilla.jss.CryptoManager; @@ -79,6 +76,9 @@ import com.netscape.cms.servlet.base.PKIService; import com.netscape.cmsutil.util.Cert; import com.netscape.cmsutil.util.Utils; +import netscape.security.pkcs.PKCS7; +import netscape.security.x509.X509CertImpl; + /** * @author Endi S. Dewata */ @@ -209,6 +209,7 @@ public class UserService extends PKIService implements UserResource { throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID", headers)); } + IConfigStore cs = CMS.getConfigStore(); IUser user; try { @@ -237,17 +238,22 @@ public class UserService extends PKIService implements UserResource { String type = user.getUserType(); if (!StringUtils.isEmpty(type)) userData.setType(type); - List profiles = user.getTpsProfiles(); - if (profiles != null) { - StringBuilder sb = new StringBuilder(); - String prefix = ""; - for (String profile: profiles) { - sb.append(prefix); - prefix = ","; - sb.append(profile); + // TODO: refactor into TPSUserService + String csType = cs.getString("cs.type"); + if (csType.equals("TPS")) { + + List profiles = user.getTpsProfiles(); + if (profiles != null) { + StringBuilder sb = new StringBuilder(); + String prefix = ""; + for (String profile: profiles) { + sb.append(prefix); + prefix = ","; + sb.append(profile); + } + + userData.setAttribute(ATTR_TPS_PROFILES, sb.toString()); } - - userData.setAttribute(ATTR_TPS_PROFILES, sb.toString()); } return userData; @@ -363,15 +369,23 @@ public class UserService extends PKIService implements UserResource { user.setState(state); } - String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES); - CMS.debug("TPS profiles: " + tpsProfiles); + // TODO: refactor into TPSUserService String csType = cs.getString("cs.type"); - if (tpsProfiles != null) { - if (!csType.equals("TPS")) { - throw new BadRequestException("Cannot set tpsProfiles on a non-TPS subsystem"); + if (csType.equals("TPS")) { + + String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES); + CMS.debug("TPS profiles: " + tpsProfiles); + if (tpsProfiles != null) { // update profiles if specified + + String[] profiles; + if (StringUtils.isEmpty(tpsProfiles)) { + profiles = new String[0]; + } else { + profiles = tpsProfiles.split(","); + } + + user.setTpsProfiles(Arrays.asList(profiles)); } - String[] profiles = tpsProfiles.split(","); - user.setTpsProfiles(Arrays.asList(profiles)); } userGroupManager.addUser(user); @@ -443,11 +457,23 @@ public class UserService extends PKIService implements UserResource { String state = userData.getState(); user.setState(state); + // TODO: refactor into TPSUserService String csType = cs.getString("cs.type"); if (csType.equals("TPS")) { + String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES); - String[] profiles = tpsProfiles.split(","); - user.setTpsProfiles(Arrays.asList(profiles)); + CMS.debug("TPS Profiles: " + tpsProfiles); + if (tpsProfiles != null) { // update profiles if specified + + String[] profiles; + if (StringUtils.isEmpty(tpsProfiles)) { + profiles = new String[0]; + } else { + profiles = tpsProfiles.split(","); + } + + user.setTpsProfiles(Arrays.asList(profiles)); + } } userGroupManager.modifyUser(user); @@ -485,6 +511,8 @@ public class UserService extends PKIService implements UserResource { @Override public Response modifyUser(String userID, UserData userData) { + CMS.debug("UserService.modifyUser(" + userID + ")"); + if (userData == null) throw new BadRequestException("User data is null."); // ensure that any low-level exceptions are reported @@ -499,11 +527,13 @@ public class UserService extends PKIService implements UserResource { IUser user = userGroupManager.createUser(userID); String fullName = userData.getFullName(); + CMS.debug("Full name: " + fullName); if (fullName != null) { user.setFullName(fullName); } String email = userData.getEmail(); + CMS.debug("Email: " + email); if (email != null) { user.setEmail(email); } @@ -520,23 +550,34 @@ public class UserService extends PKIService implements UserResource { } String phone = userData.getPhone(); + CMS.debug("Phone: " + phone); if (phone != null) { user.setPhone(phone); } String state = userData.getState(); + CMS.debug("State: " + state); if (state != null) { user.setState(state); } - String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES); + // TODO: refactor into TPSUserService String csType = cs.getString("cs.type"); - if (tpsProfiles != null) { - if (!csType.equals("TPS")) { - throw new BadRequestException("Cannot set tpsProfiles on a non-TPS subsystem"); + if (csType.equals("TPS")) { + + String tpsProfiles = userData.getAttribute(ATTR_TPS_PROFILES); + CMS.debug("TPS Profiles: " + tpsProfiles); + if (tpsProfiles != null) { // update profiles if specified + + String[] profiles; + if (StringUtils.isEmpty(tpsProfiles)) { + profiles = new String[0]; + } else { + profiles = tpsProfiles.split(","); + } + + user.setTpsProfiles(Arrays.asList(profiles)); } - String[] profiles = tpsProfiles.split(","); - user.setTpsProfiles(Arrays.asList(profiles)); } userGroupManager.modifyUser(user); diff --git a/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java index d1277279e5c020aa688d1dedce9230d293fe3fac..a11c551e5424c55b41a53318689866c66aacff73 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java @@ -25,19 +25,6 @@ import java.util.Enumeration; import java.util.List; import java.util.Vector; -import netscape.ldap.LDAPAttribute; -import netscape.ldap.LDAPAttributeSet; -import netscape.ldap.LDAPConnection; -import netscape.ldap.LDAPDN; -import netscape.ldap.LDAPEntry; -import netscape.ldap.LDAPException; -import netscape.ldap.LDAPModification; -import netscape.ldap.LDAPModificationSet; -import netscape.ldap.LDAPSearchConstraints; -import netscape.ldap.LDAPSearchResults; -import netscape.ldap.LDAPv2; -import netscape.security.x509.X509CertImpl; - import org.apache.commons.lang.StringUtils; import com.netscape.certsrv.apps.CMS; @@ -60,6 +47,19 @@ import com.netscape.cmscore.ldapconn.LdapBoundConnFactory; import com.netscape.cmscore.util.Debug; import com.netscape.cmsutil.ldap.LDAPUtil; +import netscape.ldap.LDAPAttribute; +import netscape.ldap.LDAPAttributeSet; +import netscape.ldap.LDAPConnection; +import netscape.ldap.LDAPDN; +import netscape.ldap.LDAPEntry; +import netscape.ldap.LDAPException; +import netscape.ldap.LDAPModification; +import netscape.ldap.LDAPModificationSet; +import netscape.ldap.LDAPSearchConstraints; +import netscape.ldap.LDAPSearchResults; +import netscape.ldap.LDAPv2; +import netscape.security.x509.X509CertImpl; + /** * This class defines low-level LDAP usr/grp management * usr/grp information is located remotely on another @@ -738,11 +738,15 @@ public final class UGSubsystem implements IUGSubsystem { } // TODO add audit logging for profile - if (id.getTpsProfiles() != null) { - List profiles = id.getTpsProfiles(); - for (String profile: profiles) { - attrs.add(new LDAPAttribute(LDAP_ATTR_PROFILE_ID, profile)); + List profiles = id.getTpsProfiles(); + if (profiles != null && profiles.size() > 0) { + CMS.debug("Adding " + LDAP_ATTR_PROFILE_ID + ":"); + LDAPAttribute attr = new LDAPAttribute(LDAP_ATTR_PROFILE_ID); + for (String profile : profiles) { + CMS.debug(" - " + profile); + attr.addValue(profile); } + attrs.add(attr); } LDAPEntry entry = new LDAPEntry("uid=" + LDAPUtil.escapeRDNValue(id.getUserID()) + @@ -763,12 +767,14 @@ public final class UGSubsystem implements IUGSubsystem { ldapconn.add(entry); } catch (LDAPException e) { + CMS.debug(e); log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString())); throw LDAPExceptionConverter.toPKIException(e); } catch (ELdapException e) { + CMS.debug(e); log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_ADD_USER", e.toString())); - throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ADD_USER_FAIL")); + throw new EUsrGrpException(CMS.getUserMessage("CMS_USRGRP_ADD_USER_FAIL"), e); } finally { if (ldapconn != null) @@ -1229,7 +1235,8 @@ public final class UGSubsystem implements IUGSubsystem { } } - if (user.getTpsProfiles() != null) { + List profiles = user.getTpsProfiles(); + if (profiles != null) { // TODO add audit logging for profile // replace the objectclass in case tpsProfile is not present @@ -1238,44 +1245,11 @@ public final class UGSubsystem implements IUGSubsystem { attrs.add(LDAPModification.REPLACE, new LDAPAttribute(OBJECTCLASS_ATTR, oc)); - User ldapUser = (User) getUser(user.getUserID()); - List oldProfiles = ldapUser.getTpsProfiles(); - List profiles = user.getTpsProfiles(); - - if (oldProfiles == null) { - for (String profile : profiles) { - attrs.add(LDAPModification.ADD, - new LDAPAttribute(LDAP_ATTR_PROFILE_ID, profile)); - } - } else { - for (String profile : profiles) { - boolean found = false; - for (String oldProfile : oldProfiles) { - if (profile.equals(oldProfile)) { - found = true; - break; - } - } - if (!found) { - attrs.add(LDAPModification.ADD, - new LDAPAttribute(LDAP_ATTR_PROFILE_ID, profile)); - } - } - - for (String oldProfile : oldProfiles) { - boolean found = false; - for (String profile : profiles) { - if (profile.equals(oldProfile)) { - found = true; - break; - } - } - if (!found) { - attrs.add(LDAPModification.DELETE, - new LDAPAttribute(LDAP_ATTR_PROFILE_ID, oldProfile)); - } - } + LDAPAttribute attr = new LDAPAttribute(LDAP_ATTR_PROFILE_ID); + for (String profile : profiles) { + attr.addValue(profile); } + attrs.add(LDAPModification.REPLACE, attr); } /** diff --git a/base/server/share/webapps/pki/js/pki-ui.js b/base/server/share/webapps/pki/js/pki-ui.js index 2fa47ccc48a65ff781c694662734c5ca26d055d6..cf4b44e241aee2ab7817fbebcc26b1f28dfc5148 100644 --- a/base/server/share/webapps/pki/js/pki-ui.js +++ b/base/server/share/webapps/pki/js/pki-ui.js @@ -621,7 +621,7 @@ var Table = Backbone.View.extend({ // check filter against all values in the entry var matches = false; _(entry).each(function(value, key) { - if (entry.name.indexOf(filter) >= 0) matches = true; + if (value && value.indexOf(filter) >= 0) matches = true; }); return matches; @@ -704,7 +704,7 @@ var Table = Backbone.View.extend({ // save new entry dialog.save(); - self.entries.push(dialog.entry); + self.addEntry(dialog.entry); // redraw table self.render(); @@ -713,6 +713,10 @@ var Table = Backbone.View.extend({ dialog.open(); }, + addEntry: function(entry) { + var self = this; + self.entries.push(entry); + }, remove: function(items) { var self = this; diff --git a/base/tps/shared/webapps/tps/js/user.js b/base/tps/shared/webapps/tps/js/user.js index 3a29f1dd137afc8f1157b627166c43734185f0bd..663b66fc57b77c0b5cbb146ce081cacc339680f2 100644 --- a/base/tps/shared/webapps/tps/js/user.js +++ b/base/tps/shared/webapps/tps/js/user.js @@ -86,41 +86,199 @@ var UserCollection = Collection.extend({ } }); +var UserProfilesTableItem = TableItem.extend({ + initialize: function(options) { + var self = this; + UserProfilesTableItem.__super__.initialize.call(self, options); + }, + renderColumn: function(td, templateTD) { + var self = this; + + UserProfilesTableItem.__super__.renderColumn.call(self, td, templateTD); + + $("a", td).click(function(e) { + e.preventDefault(); + self.table.open(self); + }); + } +}); + +var UserProfilesTable = Table.extend({ + initialize: function(options) { + var self = this; + options.tableItem = UserProfilesTableItem; + UserProfilesTable.__super__.initialize.call(self, options); + }, + sort: function() { + var self = this; + + // sort profiles by id + self.filteredEntries = _.sortBy(self.filteredEntries, function(entry) { + return entry.id; + }); + }, + add: function() { + var self = this; + + profiles = new ProfileCollection(); + profiles.fetch({ + success: function(collection, response, options) { + + var dialog = self.addDialog; + var select = dialog.$(".modal-body select").empty(); + + $('