From a6449baac818ba110e485d96dae9cac97137c3c2 Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Mon, 11 Feb 2013 13:16:44 -0500 Subject: Added CLI to manage user membership. New CLI's have been added to search, add, and remove user membership. The group member management code has been refactored into a processor to allow reuse. Ticket #190 --- .../ca/CertificateAuthorityApplication.java | 2 + .../certsrv/group/GroupMemberCollection.java | 2 + .../netscape/certsrv/group/GroupMemberData.java | 16 + .../src/com/netscape/certsrv/user/UserClient.java | 16 + .../certsrv/user/UserMembershipCollection.java | 85 +++++ .../netscape/certsrv/user/UserMembershipData.java | 99 ++++++ .../certsrv/user/UserMembershipResource.java | 60 ++++ .../cms/servlet/admin/GroupMemberProcessor.java | 394 +++++++++++++++++++++ .../cms/servlet/admin/GroupMemberService.java | 331 ++--------------- .../cms/servlet/admin/UserCertService.java | 4 +- .../cms/servlet/admin/UserMembershipService.java | 172 +++++++++ .../netscape/cms/servlet/admin/UserService.java | 2 +- .../netscape/cms/servlet/processors/Processor.java | 49 +++ .../src/com/netscape/cmstools/group/GroupCLI.java | 2 +- .../cmstools/user/UserAddMembershipCLI.java | 57 +++ .../src/com/netscape/cmstools/user/UserCLI.java | 14 + .../cmstools/user/UserFindMembershipCLI.java | 104 ++++++ .../cmstools/user/UserRemoveMembershipCLI.java | 54 +++ .../kra/KeyRecoveryAuthorityApplication.java | 2 + .../src/com/netscape/ocsp/OCSPApplication.java | 2 + base/tks/src/com/netscape/tks/TKSApplication.java | 2 + 21 files changed, 1158 insertions(+), 311 deletions(-) create mode 100644 base/common/src/com/netscape/certsrv/user/UserMembershipCollection.java create mode 100644 base/common/src/com/netscape/certsrv/user/UserMembershipData.java create mode 100644 base/common/src/com/netscape/certsrv/user/UserMembershipResource.java create mode 100644 base/common/src/com/netscape/cms/servlet/admin/GroupMemberProcessor.java create mode 100644 base/common/src/com/netscape/cms/servlet/admin/UserMembershipService.java create mode 100644 base/java-tools/src/com/netscape/cmstools/user/UserAddMembershipCLI.java create mode 100644 base/java-tools/src/com/netscape/cmstools/user/UserFindMembershipCLI.java create mode 100644 base/java-tools/src/com/netscape/cmstools/user/UserRemoveMembershipCLI.java diff --git a/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java b/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java index 14b44e5d7..4c81ff925 100644 --- a/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java +++ b/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java @@ -16,6 +16,7 @@ import com.netscape.cms.servlet.admin.GroupService; import com.netscape.cms.servlet.admin.KRAConnectorService; import com.netscape.cms.servlet.admin.SystemCertService; import com.netscape.cms.servlet.admin.UserCertService; +import com.netscape.cms.servlet.admin.UserMembershipService; import com.netscape.cms.servlet.admin.UserService; import com.netscape.cms.servlet.cert.CertService; import com.netscape.cms.servlet.csadmin.SecurityDomainService; @@ -46,6 +47,7 @@ public class CertificateAuthorityApplication extends Application { classes.add(GroupMemberService.class); classes.add(GroupService.class); classes.add(UserCertService.class); + classes.add(UserMembershipService.class); classes.add(UserService.class); // system certs diff --git a/base/common/src/com/netscape/certsrv/group/GroupMemberCollection.java b/base/common/src/com/netscape/certsrv/group/GroupMemberCollection.java index d19d939ad..6ec013bca 100644 --- a/base/common/src/com/netscape/certsrv/group/GroupMemberCollection.java +++ b/base/common/src/com/netscape/certsrv/group/GroupMemberCollection.java @@ -69,10 +69,12 @@ public class GroupMemberCollection { GroupMemberData member1 = new GroupMemberData(); member1.setID("User 1"); + member1.setGroupID("Group 1"); response.addMember(member1); GroupMemberData member2 = new GroupMemberData(); member2.setID("User 2"); + member2.setGroupID("Group 1"); response.addMember(member2); JAXBContext context = JAXBContext.newInstance(GroupMemberCollection.class); diff --git a/base/common/src/com/netscape/certsrv/group/GroupMemberData.java b/base/common/src/com/netscape/certsrv/group/GroupMemberData.java index 11f3a2147..8502f3e8f 100644 --- a/base/common/src/com/netscape/certsrv/group/GroupMemberData.java +++ b/base/common/src/com/netscape/certsrv/group/GroupMemberData.java @@ -34,6 +34,7 @@ import com.netscape.certsrv.common.Constants; public class GroupMemberData { String id; + String groupID; Link link; @@ -47,6 +48,15 @@ public class GroupMemberData { this.id = id; } + @XmlAttribute(name="GroupID") + public String getGroupID() { + return groupID; + } + + public void setGroupID(String groupID) { + this.groupID = groupID; + } + @XmlElement(name="Link") public Link getLink() { return link; @@ -60,6 +70,7 @@ public class GroupMemberData { public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + ((groupID == null) ? 0 : groupID.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @@ -73,6 +84,11 @@ public class GroupMemberData { if (getClass() != obj.getClass()) return false; GroupMemberData other = (GroupMemberData) obj; + if (groupID == null) { + if (other.groupID != null) + return false; + } else if (!groupID.equals(other.groupID)) + return false; if (id == null) { if (other.id != null) return false; diff --git a/base/common/src/com/netscape/certsrv/user/UserClient.java b/base/common/src/com/netscape/certsrv/user/UserClient.java index 23136200d..2dd350354 100644 --- a/base/common/src/com/netscape/certsrv/user/UserClient.java +++ b/base/common/src/com/netscape/certsrv/user/UserClient.java @@ -32,6 +32,7 @@ public class UserClient extends PKIClient { public UserResource userClient; public UserCertResource userCertClient; + public UserMembershipResource userMembershipClient; public UserClient(PKIConnection connection) throws URISyntaxException { super(connection); @@ -46,6 +47,7 @@ public class UserClient extends PKIClient { public void init() throws URISyntaxException { userClient = createProxy(UserResource.class); userCertClient = createProxy(UserCertResource.class); + userMembershipClient = createProxy(UserMembershipResource.class); } public UserCollection findUsers(String filter, Integer start, Integer size) { @@ -89,4 +91,18 @@ public class UserClient extends PKIClient { public void removeUserCert(String userID, String certID) { userCertClient.removeUserCert(userID, certID); } + + public UserMembershipCollection findUserMemberships(String userID, Integer start, Integer size) { + return userMembershipClient.findUserMemberships(userID, start, size); + } + + public UserMembershipData addUserMembership(String userID, String groupID) { + @SuppressWarnings("unchecked") + ClientResponse response = (ClientResponse)userMembershipClient.addUserMembership(userID, groupID); + return getEntity(response); + } + + public void removeUserMembership(String userD, String groupID) { + userMembershipClient.removeUserMembership(userD, groupID); + } } diff --git a/base/common/src/com/netscape/certsrv/user/UserMembershipCollection.java b/base/common/src/com/netscape/certsrv/user/UserMembershipCollection.java new file mode 100644 index 000000000..069840d13 --- /dev/null +++ b/base/common/src/com/netscape/certsrv/user/UserMembershipCollection.java @@ -0,0 +1,85 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.certsrv.user; + +import java.util.ArrayList; +import java.util.Collection; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.jboss.resteasy.plugins.providers.atom.Link; + +/** + * @author Endi S. Dewata + */ +@XmlRootElement(name="UserMemberships") +public class UserMembershipCollection { + + Collection memberships = new ArrayList(); + Collection links = new ArrayList(); + + @XmlElement(name="Membership") + public Collection getMemberships() { + return memberships; + } + + public void setMemberships(Collection members) { + this.memberships = members; + } + + public void addMembership(UserMembershipData member) { + memberships.add(member); + } + + @XmlElement(name="Link") + public Collection getLinks() { + return links; + } + + public void setLink(Collection links) { + this.links = links; + } + + public void addLink(Link link) { + links.add(link); + } + + public static void main(String args[]) throws Exception { + + UserMembershipCollection response = new UserMembershipCollection(); + + UserMembershipData membership1 = new UserMembershipData(); + membership1.setID("Group 1"); + membership1.setUserID("User 1"); + response.addMembership(membership1); + + UserMembershipData membership2 = new UserMembershipData(); + membership2.setID("Group 2"); + membership2.setUserID("User 1"); + response.addMembership(membership2); + + JAXBContext context = JAXBContext.newInstance(UserMembershipCollection.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.marshal(response, System.out); + } +} diff --git a/base/common/src/com/netscape/certsrv/user/UserMembershipData.java b/base/common/src/com/netscape/certsrv/user/UserMembershipData.java new file mode 100644 index 000000000..8db70e21e --- /dev/null +++ b/base/common/src/com/netscape/certsrv/user/UserMembershipData.java @@ -0,0 +1,99 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.certsrv.user; + +import javax.ws.rs.FormParam; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.jboss.resteasy.plugins.providers.atom.Link; + +import com.netscape.certsrv.common.Constants; + +/** + * @author Endi S. Dewata + */ +@XmlRootElement(name="UserMembership") +public class UserMembershipData { + + String id; + String userID; + + Link link; + + @FormParam(Constants.PR_GROUP_GROUP) + @XmlAttribute(name="id") + public String getID() { + return id; + } + + public void setID(String id) { + this.id = id; + } + + @XmlElement(name="UserID") + public String getUserID() { + return userID; + } + + public void setUserID(String userID) { + this.userID = userID; + } + + @XmlElement(name="Link") + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((userID == null) ? 0 : userID.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + UserMembershipData other = (UserMembershipData) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + 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/common/src/com/netscape/certsrv/user/UserMembershipResource.java b/base/common/src/com/netscape/certsrv/user/UserMembershipResource.java new file mode 100644 index 000000000..eedc2c961 --- /dev/null +++ b/base/common/src/com/netscape/certsrv/user/UserMembershipResource.java @@ -0,0 +1,60 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.certsrv.user; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.jboss.resteasy.annotations.ClientResponseType; + +import com.netscape.certsrv.acls.ACLMapping; + +/** + * @author Endi S. Dewata + */ +@Path("admin/users/{userID}/memberships") +@ACLMapping("admin.users") +public interface UserMembershipResource { + + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public UserMembershipCollection findUserMemberships( + @PathParam("userID") String userID, + @QueryParam("start") Integer start, + @QueryParam("size") Integer size); + + @POST + @ClientResponseType(entityType=UserMembershipData.class) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response addUserMembership(@PathParam("userID") String userID, String groupID); + + @DELETE + @Path("{groupID}") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void removeUserMembership(@PathParam("userID") String userID, @PathParam("groupID") String groupID); +} diff --git a/base/common/src/com/netscape/cms/servlet/admin/GroupMemberProcessor.java b/base/common/src/com/netscape/cms/servlet/admin/GroupMemberProcessor.java new file mode 100644 index 000000000..bb8b73c10 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/admin/GroupMemberProcessor.java @@ -0,0 +1,394 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.admin; + +import java.net.URI; +import java.net.URLEncoder; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Map; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.jboss.resteasy.plugins.providers.atom.Link; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.BadRequestException; +import com.netscape.certsrv.base.ConflictingOperationException; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.base.PKIException; +import com.netscape.certsrv.base.ResourceNotFoundException; +import com.netscape.certsrv.base.SessionContext; +import com.netscape.certsrv.common.OpDef; +import com.netscape.certsrv.common.ScopeDef; +import com.netscape.certsrv.group.GroupMemberCollection; +import com.netscape.certsrv.group.GroupMemberData; +import com.netscape.certsrv.group.GroupMemberResource; +import com.netscape.certsrv.group.GroupNotFoundException; +import com.netscape.certsrv.logging.AuditFormat; +import com.netscape.certsrv.logging.IAuditor; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.usrgrp.IGroup; +import com.netscape.certsrv.usrgrp.IUGSubsystem; +import com.netscape.cms.servlet.processors.Processor; + +/** + * @author Endi S. Dewata + */ +public class GroupMemberProcessor extends Processor { + + public final static int DEFAULT_SIZE = 20; + + public final static String MULTI_ROLE_ENABLE = "multiroles.enable"; + public final static String MULTI_ROLE_ENFORCE_GROUP_LIST = "multiroles.false.groupEnforceList"; + + public static String[] multiRoleGroupEnforceList; + + public IUGSubsystem userGroupManager = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG); + + protected UriInfo uriInfo; + + public GroupMemberProcessor(Locale locale) throws EBaseException { + super("group", locale); + } + + public UriInfo getUriInfo() { + return uriInfo; + } + + public void setUriInfo(UriInfo uriInfo) { + this.uriInfo = uriInfo; + } + + public GroupMemberData createGroupMemberData(String groupID, String memberID) throws Exception { + + GroupMemberData groupMemberData = new GroupMemberData(); + groupMemberData.setID(memberID); + groupMemberData.setGroupID(groupID); + + URI uri = uriInfo.getBaseUriBuilder() + .path(GroupMemberResource.class) + .path("{userID}") + .build( + URLEncoder.encode(groupID, "UTF-8"), + URLEncoder.encode(memberID, "UTF-8")); + + groupMemberData.setLink(new Link("self", uri)); + + return groupMemberData; + } + + public GroupMemberCollection findGroupMembers(String groupID, Integer start, Integer size) { + try { + start = start == null ? 0 : start; + size = size == null ? DEFAULT_SIZE : size; + + if (groupID == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); + throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); + } + + IGroup group = userGroupManager.getGroupFromName(groupID); + if (group == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); + throw new GroupNotFoundException(groupID); + } + + GroupMemberCollection response = new GroupMemberCollection(); + + Enumeration members = group.getMemberNames(); + + int i = 0; + + // skip to the start of the page + for ( ; i 0) { + URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start-size, 0)).build(); + response.addLink(new Link("prev", uri)); + } + + if (start+size < i) { + URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start+size).build(); + response.addLink(new Link("next", uri)); + } + + return response; + + } catch (PKIException e) { + throw e; + + } catch (Exception e) { + CMS.debug(e); + throw new PKIException(getUserMessage("CMS_INTERNAL_ERROR")); + } + } + + public GroupMemberData getGroupMember(String groupID, String memberID) { + try { + if (groupID == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); + throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); + } + + IGroup group = userGroupManager.getGroupFromName(groupID); + if (group == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); + throw new GroupNotFoundException(groupID); + } + + Enumeration e = group.getMemberNames(); + while (e.hasMoreElements()) { + String memberName = e.nextElement(); + if (!memberName.equals(memberID)) continue; + + GroupMemberData groupMemberData = createGroupMemberData(groupID, memberID); + return groupMemberData; + } + + throw new ResourceNotFoundException("Group member " + memberID + " not found"); + + } catch (PKIException e) { + throw e; + + } catch (Exception e) { + log(ILogger.LL_FAILURE, e.toString()); + throw new PKIException(e.getMessage()); + } + } + + public Response addGroupMember(GroupMemberData groupMemberData) { + String groupID = groupMemberData.getGroupID(); + try { + if (groupID == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); + throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); + } + + IGroup group = userGroupManager.getGroupFromName(groupID); + if (group == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); + throw new GroupNotFoundException(groupID); + } + + String memberID = groupMemberData.getID(); + boolean multiRole = true; + + try { + IConfigStore config = CMS.getConfigStore(); + multiRole = config.getBoolean(MULTI_ROLE_ENABLE); + } catch (Exception e) { + // ignore + } + + if (multiRole) { + // a user can be a member of multiple groups + userGroupManager.addUserToGroup(group, memberID); + + } else { + // a user can be a member of at most one group in the enforce list + if (isGroupInMultiRoleEnforceList(groupID)) { + // make sure the user is not already a member in another group in the list + if (!isDuplicate(groupID, memberID)) { + userGroupManager.addUserToGroup(group, memberID); + } else { + throw new ConflictingOperationException(CMS.getUserMessage("CMS_BASE_DUPLICATE_ROLES", memberID)); + } + + } else { + // the user can be a member of multiple groups outside the list + userGroupManager.addUserToGroup(group, memberID); + } + } + + // for audit log + SessionContext sContext = SessionContext.getContext(); + String adminId = (String) sContext.get(SessionContext.USER_ID); + + logger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP, + AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT, + new Object[] { adminId, memberID, groupID }); + + auditAddGroupMember(groupID, groupMemberData, ILogger.SUCCESS); + + // read the data back + groupMemberData = getGroupMember(groupID, memberID); + + return Response + .created(groupMemberData.getLink().getHref()) + .entity(groupMemberData) + .type(MediaType.APPLICATION_XML) + .build(); + + } catch (PKIException e) { + auditAddGroupMember(groupID, groupMemberData, ILogger.FAILURE); + throw e; + + } catch (Exception e) { + log(ILogger.LL_FAILURE, e.toString()); + auditAddGroupMember(groupID, groupMemberData, ILogger.FAILURE); + throw new PKIException(getUserMessage("CMS_USRGRP_USER_ADD_FAILED")); + } + } + + public boolean isGroupInMultiRoleEnforceList(String groupID) { + + if (groupID == null || groupID.equals("")) { + return true; + } + + String groupList = null; + if (multiRoleGroupEnforceList == null) { + try { + IConfigStore config = CMS.getConfigStore(); + groupList = config.getString(MULTI_ROLE_ENFORCE_GROUP_LIST); + } catch (Exception e) { + // ignore + } + + if (groupList != null && !groupList.equals("")) { + multiRoleGroupEnforceList = groupList.split(","); + for (int j = 0; j < multiRoleGroupEnforceList.length; j++) { + multiRoleGroupEnforceList[j] = multiRoleGroupEnforceList[j].trim(); + } + } + } + + if (multiRoleGroupEnforceList == null) + return true; + + for (int i = 0; i < multiRoleGroupEnforceList.length; i++) { + if (groupID.equals(multiRoleGroupEnforceList[i])) { + return true; + } + } + + return false; + } + + public boolean isDuplicate(String groupID, String memberID) { + + // Let's not mess with users that are already a member of this group + try { + boolean isMember = userGroupManager.isMemberOf(memberID, groupID); + if (isMember == true) return false; + + } catch (Exception e) { + // ignore + } + + try { + Enumeration groups = userGroupManager.listGroups("*"); + while (groups.hasMoreElements()) { + IGroup group = groups.nextElement(); + String name = group.getName(); + + Enumeration g = userGroupManager.findGroups(name); + IGroup g1 = g.nextElement(); + + if (!name.equals(groupID)) { + if (isGroupInMultiRoleEnforceList(name)) { + Enumeration members = g1.getMemberNames(); + while (members.hasMoreElements()) { + String m1 = members.nextElement(); + if (m1.equals(memberID)) + return true; + } + } + } + } + } catch (Exception e) { + // ignore + } + + return false; + } + + public void removeGroupMember(String groupID, String memberID) { + GroupMemberData groupMemberData = new GroupMemberData(); + groupMemberData.setID(memberID); + groupMemberData.setGroupID(groupID); + removeGroupMember(groupMemberData); + } + + public void removeGroupMember(GroupMemberData groupMemberData) { + String groupID = groupMemberData.getGroupID(); + try { + if (groupID == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); + throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); + } + + IGroup group = userGroupManager.getGroupFromName(groupID); + if (group == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); + throw new GroupNotFoundException(groupID); + } + + String memberID = groupMemberData.getID(); + userGroupManager.removeUserFromGroup(group, memberID); + + // for audit log + SessionContext sContext = SessionContext.getContext(); + String adminId = (String) sContext.get(SessionContext.USER_ID); + + logger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP, + AuditFormat.LEVEL, AuditFormat.REMOVEUSERGROUPFORMAT, + new Object[] { adminId, memberID, groupID }); + + auditDeleteGroupMember(groupID, groupMemberData, ILogger.SUCCESS); + + } catch (PKIException e) { + auditDeleteGroupMember(groupID, groupMemberData, ILogger.FAILURE); + throw e; + + } catch (Exception e) { + log(ILogger.LL_FAILURE, e.toString()); + auditDeleteGroupMember(groupID, groupMemberData, ILogger.FAILURE); + throw new PKIException(getUserMessage("CMS_USRGRP_USER_ADD_FAILED")); + } + } + + public void log(int level, String message) { + log(ILogger.S_USRGRP, level, message); + } + + public void auditAddGroupMember(String groupID, GroupMemberData groupMemberData, String status) { + audit(OpDef.OP_ADD, groupID, getParams(groupMemberData), status); + } + + public void auditDeleteGroupMember(String groupID, GroupMemberData groupMemberData, String status) { + audit(OpDef.OP_DELETE, groupID, getParams(groupMemberData), status); + } + + public void audit(String type, String id, Map params, String status) { + audit(IAuditor.LOGGING_SIGNED_AUDIT_CONFIG_ROLE, ScopeDef.SC_GROUP_MEMBERS, type, id, params, status); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/admin/GroupMemberService.java b/base/common/src/com/netscape/cms/servlet/admin/GroupMemberService.java index cd17f5b6c..989b89db0 100644 --- a/base/common/src/com/netscape/cms/servlet/admin/GroupMemberService.java +++ b/base/common/src/com/netscape/cms/servlet/admin/GroupMemberService.java @@ -18,35 +18,12 @@ package com.netscape.cms.servlet.admin; -import java.net.URI; -import java.net.URLEncoder; -import java.util.Enumeration; -import java.util.Map; - -import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.jboss.resteasy.plugins.providers.atom.Link; - -import com.netscape.certsrv.apps.CMS; -import com.netscape.certsrv.base.BadRequestException; -import com.netscape.certsrv.base.ConflictingOperationException; -import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.PKIException; -import com.netscape.certsrv.base.ResourceNotFoundException; -import com.netscape.certsrv.base.SessionContext; -import com.netscape.certsrv.common.OpDef; -import com.netscape.certsrv.common.ScopeDef; import com.netscape.certsrv.group.GroupMemberCollection; import com.netscape.certsrv.group.GroupMemberData; import com.netscape.certsrv.group.GroupMemberResource; -import com.netscape.certsrv.group.GroupNotFoundException; -import com.netscape.certsrv.logging.AuditFormat; -import com.netscape.certsrv.logging.IAuditor; -import com.netscape.certsrv.logging.ILogger; -import com.netscape.certsrv.user.UserResource; -import com.netscape.certsrv.usrgrp.IGroup; -import com.netscape.certsrv.usrgrp.IUGSubsystem; import com.netscape.cms.servlet.base.PKIService; /** @@ -54,330 +31,70 @@ import com.netscape.cms.servlet.base.PKIService; */ public class GroupMemberService extends PKIService implements GroupMemberResource { - public final static int DEFAULT_SIZE = 20; - - public final static String MULTI_ROLE_ENABLE = "multiroles.enable"; - public final static String MULTI_ROLE_ENFORCE_GROUP_LIST = "multiroles.false.groupEnforceList"; - - public static String[] multiRoleGroupEnforceList; - - public IUGSubsystem userGroupManager = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG); - - public GroupMemberData createGroupMemberData(String memberID) throws Exception { - - GroupMemberData groupMemberData = new GroupMemberData(); - - groupMemberData.setID(memberID); - - String userID = URLEncoder.encode(memberID, "UTF-8"); - URI uri = uriInfo.getBaseUriBuilder().path(UserResource.class).path("{userID}").build(userID); - groupMemberData.setLink(new Link("self", uri)); - - return groupMemberData; - } - @Override public GroupMemberCollection findGroupMembers(String groupID, Integer start, Integer size) { try { - start = start == null ? 0 : start; - size = size == null ? DEFAULT_SIZE : size; - - if (groupID == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); - throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); - } - - IGroup group = userGroupManager.getGroupFromName(groupID); - if (group == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); - throw new GroupNotFoundException(groupID); - } - - GroupMemberCollection response = new GroupMemberCollection(); - - Enumeration members = group.getMemberNames(); - - int i = 0; - - // skip to the start of the page - for ( ; i 0) { - URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start-size, 0)).build(); - response.addLink(new Link("prev", uri)); - } - - if (start+size < i) { - URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start+size).build(); - response.addLink(new Link("next", uri)); - } - - return response; + GroupMemberProcessor processor = new GroupMemberProcessor(getLocale()); + processor.setUriInfo(uriInfo); + return processor.findGroupMembers(groupID, start, size); } catch (PKIException e) { throw e; } catch (Exception e) { - CMS.debug(e); - throw new PKIException(getUserMessage("CMS_INTERNAL_ERROR")); + throw new PKIException(e.getMessage(), e); } } @Override - public Response addGroupMember(String groupID, String memberID) { - GroupMemberData groupMemberData = new GroupMemberData(); - groupMemberData.setID(memberID); - return addGroupMember(groupID, groupMemberData); - } - - public Response addGroupMember(String groupID, GroupMemberData groupMemberData) { - + public GroupMemberData getGroupMember(String groupID, String memberID) { try { - if (groupID == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); - throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); - } - - IGroup group = userGroupManager.getGroupFromName(groupID); - if (group == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); - throw new GroupNotFoundException(groupID); - } - - String memberID = groupMemberData.getID(); - boolean multiRole = true; - - try { - IConfigStore config = CMS.getConfigStore(); - multiRole = config.getBoolean(MULTI_ROLE_ENABLE); - } catch (Exception e) { - // ignore - } - - if (multiRole) { - // a user can be a member of multiple groups - userGroupManager.addUserToGroup(group, memberID); - - } else { - // a user can be a member of at most one group in the enforce list - if (isGroupInMultiRoleEnforceList(groupID)) { - // make sure the user is not already a member in another group in the list - if (!isDuplicate(groupID, memberID)) { - userGroupManager.addUserToGroup(group, memberID); - } else { - throw new ConflictingOperationException(CMS.getUserMessage("CMS_BASE_DUPLICATE_ROLES", memberID)); - } - - } else { - // the user can be a member of multiple groups outside the list - userGroupManager.addUserToGroup(group, memberID); - } - } - - // for audit log - SessionContext sContext = SessionContext.getContext(); - String adminId = (String) sContext.get(SessionContext.USER_ID); - - logger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP, - AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT, - new Object[] { adminId, memberID, groupID }); - - auditAddGroupMember(groupID, groupMemberData, ILogger.SUCCESS); - - // read the data back - groupMemberData = getGroupMember(groupID, memberID); - - return Response - .created(groupMemberData.getLink().getHref()) - .entity(groupMemberData) - .type(MediaType.APPLICATION_XML) - .build(); + GroupMemberProcessor processor = new GroupMemberProcessor(getLocale()); + processor.setUriInfo(uriInfo); + return processor.getGroupMember(groupID, memberID); } catch (PKIException e) { - auditAddGroupMember(groupID, groupMemberData, ILogger.FAILURE); throw e; } catch (Exception e) { - log(ILogger.LL_FAILURE, e.toString()); - auditAddGroupMember(groupID, groupMemberData, ILogger.FAILURE); - throw new PKIException(getUserMessage("CMS_USRGRP_USER_ADD_FAILED")); - } - } - - public boolean isGroupInMultiRoleEnforceList(String groupID) { - - if (groupID == null || groupID.equals("")) { - return true; - } - - String groupList = null; - if (multiRoleGroupEnforceList == null) { - try { - IConfigStore config = CMS.getConfigStore(); - groupList = config.getString(MULTI_ROLE_ENFORCE_GROUP_LIST); - } catch (Exception e) { - // ignore - } - - if (groupList != null && !groupList.equals("")) { - multiRoleGroupEnforceList = groupList.split(","); - for (int j = 0; j < multiRoleGroupEnforceList.length; j++) { - multiRoleGroupEnforceList[j] = multiRoleGroupEnforceList[j].trim(); - } - } - } - - if (multiRoleGroupEnforceList == null) - return true; - - for (int i = 0; i < multiRoleGroupEnforceList.length; i++) { - if (groupID.equals(multiRoleGroupEnforceList[i])) { - return true; - } - } - - return false; - } - - public boolean isDuplicate(String groupID, String memberID) { - - // Let's not mess with users that are already a member of this group - try { - boolean isMember = userGroupManager.isMemberOf(memberID, groupID); - if (isMember == true) return false; - - } catch (Exception e) { - // ignore - } - - try { - Enumeration groups = userGroupManager.listGroups("*"); - while (groups.hasMoreElements()) { - IGroup group = groups.nextElement(); - String name = group.getName(); - - Enumeration g = userGroupManager.findGroups(name); - IGroup g1 = g.nextElement(); - - if (!name.equals(groupID)) { - if (isGroupInMultiRoleEnforceList(name)) { - Enumeration members = g1.getMemberNames(); - while (members.hasMoreElements()) { - String m1 = members.nextElement(); - if (m1.equals(memberID)) - return true; - } - } - } - } - } catch (Exception e) { - // ignore + throw new PKIException(e.getMessage(), e); } - - return false; } @Override - public GroupMemberData getGroupMember(String groupID, String memberID) { + public Response addGroupMember(String groupID, String memberID) { + GroupMemberData groupMemberData = new GroupMemberData(); + groupMemberData.setID(memberID); + groupMemberData.setGroupID(groupID); + return addGroupMember(groupMemberData); + } + public Response addGroupMember(GroupMemberData groupMemberData) { try { - if (groupID == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); - throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); - } - - IGroup group = userGroupManager.getGroupFromName(groupID); - if (group == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); - throw new GroupNotFoundException(groupID); - } - - Enumeration e = group.getMemberNames(); - while (e.hasMoreElements()) { - String memberName = e.nextElement(); - if (!memberName.equals(memberID)) continue; - - GroupMemberData groupMemberData = createGroupMemberData(memberID); - return groupMemberData; - } - - throw new ResourceNotFoundException("Group member " + memberID + " not found"); + GroupMemberProcessor processor = new GroupMemberProcessor(getLocale()); + processor.setUriInfo(uriInfo); + return processor.addGroupMember(groupMemberData); } catch (PKIException e) { throw e; } catch (Exception e) { - log(ILogger.LL_FAILURE, e.toString()); - throw new PKIException(e.getMessage()); + throw new PKIException(e.getMessage(), e); } } @Override public void removeGroupMember(String groupID, String memberID) { - GroupMemberData groupMemberData = new GroupMemberData(); - groupMemberData.setID(memberID); - removeGroupMember(groupID, groupMemberData); - } - - public void removeGroupMember(String groupID, GroupMemberData groupMemberData) { try { - if (groupID == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); - throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); - } - - IGroup group = userGroupManager.getGroupFromName(groupID); - if (group == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_GROUP_NOT_EXIST")); - throw new GroupNotFoundException(groupID); - } - - String member = groupMemberData.getID(); - userGroupManager.removeUserFromGroup(group, member); - - // for audit log - SessionContext sContext = SessionContext.getContext(); - String adminId = (String) sContext.get(SessionContext.USER_ID); - - logger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP, - AuditFormat.LEVEL, AuditFormat.REMOVEUSERGROUPFORMAT, - new Object[] { adminId, member, groupID }); - - auditDeleteGroupMember(groupID, groupMemberData, ILogger.SUCCESS); + GroupMemberProcessor processor = new GroupMemberProcessor(getLocale()); + processor.setUriInfo(uriInfo); + processor.removeGroupMember(groupID, memberID); } catch (PKIException e) { - auditDeleteGroupMember(groupID, groupMemberData, ILogger.FAILURE); throw e; } catch (Exception e) { - log(ILogger.LL_FAILURE, e.toString()); - auditDeleteGroupMember(groupID, groupMemberData, ILogger.FAILURE); - throw new PKIException(getUserMessage("CMS_USRGRP_USER_ADD_FAILED")); + throw new PKIException(e.getMessage(), e); } } - - public void log(int level, String message) { - log(ILogger.S_USRGRP, level, message); - } - - public void auditAddGroupMember(String groupID, GroupMemberData groupMemberData, String status) { - audit(OpDef.OP_ADD, groupID, getParams(groupMemberData), status); - } - - public void auditDeleteGroupMember(String groupID, GroupMemberData groupMemberData, String status) { - audit(OpDef.OP_DELETE, groupID, getParams(groupMemberData), status); - } - - public void audit(String type, String id, Map params, String status) { - audit(IAuditor.LOGGING_SIGNED_AUDIT_CONFIG_ROLE, ScopeDef.SC_GROUP_MEMBERS, type, id, params, status); - } } diff --git a/base/common/src/com/netscape/cms/servlet/admin/UserCertService.java b/base/common/src/com/netscape/cms/servlet/admin/UserCertService.java index 57051040a..efefcca8c 100644 --- a/base/common/src/com/netscape/cms/servlet/admin/UserCertService.java +++ b/base/common/src/com/netscape/cms/servlet/admin/UserCertService.java @@ -112,7 +112,7 @@ public class UserCertService extends PKIService implements UserCertResource { if (user == null) { log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_USER_NOT_EXIST")); - throw new UserNotFoundException(getUserMessage("CMS_USRGRP_SRVLT_USER_NOT_EXIST")); + throw new UserNotFoundException(userID); } UserCertCollection response = new UserCertCollection(); @@ -164,7 +164,7 @@ public class UserCertService extends PKIService implements UserCertResource { if (user == null) { log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_USER_NOT_EXIST")); - throw new UserNotFoundException(getUserMessage("CMS_USRGRP_SRVLT_USER_NOT_EXIST")); + throw new UserNotFoundException(userID); } X509Certificate[] certs = user.getX509Certificates(); diff --git a/base/common/src/com/netscape/cms/servlet/admin/UserMembershipService.java b/base/common/src/com/netscape/cms/servlet/admin/UserMembershipService.java new file mode 100644 index 000000000..c87368a97 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/admin/UserMembershipService.java @@ -0,0 +1,172 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.servlet.admin; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLEncoder; +import java.util.Enumeration; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.jboss.resteasy.plugins.providers.atom.Link; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.BadRequestException; +import com.netscape.certsrv.base.PKIException; +import com.netscape.certsrv.base.UserNotFoundException; +import com.netscape.certsrv.group.GroupMemberData; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.user.UserMembershipCollection; +import com.netscape.certsrv.user.UserMembershipData; +import com.netscape.certsrv.user.UserMembershipResource; +import com.netscape.certsrv.usrgrp.IGroup; +import com.netscape.certsrv.usrgrp.IUGSubsystem; +import com.netscape.certsrv.usrgrp.IUser; +import com.netscape.cms.servlet.base.PKIService; + +/** + * @author Endi S. Dewata + */ +public class UserMembershipService extends PKIService implements UserMembershipResource { + + public final static int DEFAULT_SIZE = 20; + + public IUGSubsystem userGroupManager = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG); + + public UserMembershipData createUserMembershipData(String userID, String groupID) throws UnsupportedEncodingException { + + UserMembershipData userMembershipData = new UserMembershipData(); + userMembershipData.setID(groupID); + userMembershipData.setUserID(userID); + + URI uri = uriInfo.getBaseUriBuilder().path(UserMembershipResource.class) + .path("{groupID}") + .build( + URLEncoder.encode(userID, "UTF-8"), + URLEncoder.encode(groupID, "UTF-8")); + + userMembershipData.setLink(new Link("self", uri)); + + return userMembershipData; + } + + @Override + public UserMembershipCollection findUserMemberships(String userID, Integer start, Integer size) { + try { + start = start == null ? 0 : start; + size = size == null ? DEFAULT_SIZE : size; + + if (userID == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_NULL_RS_ID")); + throw new BadRequestException(getUserMessage("CMS_ADMIN_SRVLT_NULL_RS_ID")); + } + + IUser user = userGroupManager.getUser(userID); + + if (user == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_USER_NOT_EXIST")); + throw new UserNotFoundException(userID); + } + + UserMembershipCollection response = new UserMembershipCollection(); + + Enumeration groups = userGroupManager.findGroupsByUser(user.getUserDN()); + + int i = 0; + + // skip to the start of the page + for ( ; i 0) { + URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start-size, 0)).build(); + response.addLink(new Link("prev", uri)); + } + + if (start+size < i) { + URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start+size).build(); + response.addLink(new Link("next", uri)); + } + + return response; + + } catch (PKIException e) { + throw e; + + } catch (Exception e) { + throw new PKIException(e.getMessage(), e); + } + } + + @Override + public Response addUserMembership(String userID, String groupID) { + try { + GroupMemberData groupMemberData = new GroupMemberData(); + groupMemberData.setID(userID); + groupMemberData.setGroupID(groupID); + + GroupMemberProcessor processor = new GroupMemberProcessor(getLocale()); + processor.setUriInfo(uriInfo); + processor.addGroupMember(groupMemberData); + + UserMembershipData userMembershipData = createUserMembershipData(userID, groupID); + + return Response + .created(userMembershipData.getLink().getHref()) + .entity(userMembershipData) + .type(MediaType.APPLICATION_XML) + .build(); + + } catch (PKIException e) { + throw e; + + } catch (Exception e) { + throw new PKIException(e.getMessage(), e); + } + } + + @Override + public void removeUserMembership(String userID, String groupID) { + try { + GroupMemberProcessor processor = new GroupMemberProcessor(getLocale()); + processor.setUriInfo(uriInfo); + processor.removeGroupMember(groupID, userID); + + } catch (PKIException e) { + throw e; + + } catch (Exception e) { + throw new PKIException(e.getMessage(), e); + } + } + + public void log(int level, String message) { + log(ILogger.S_USRGRP, level, message); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/admin/UserService.java b/base/common/src/com/netscape/cms/servlet/admin/UserService.java index 901d3891c..947d1731e 100644 --- a/base/common/src/com/netscape/cms/servlet/admin/UserService.java +++ b/base/common/src/com/netscape/cms/servlet/admin/UserService.java @@ -161,7 +161,7 @@ public class UserService extends PKIService implements UserResource { if (user == null) { log(ILogger.LL_FAILURE, CMS.getLogMessage("USRGRP_SRVLT_USER_NOT_EXIST")); - throw new UserNotFoundException(getUserMessage("CMS_USRGRP_SRVLT_USER_NOT_EXIST")); + throw new UserNotFoundException(userID); } UserData userData = createUserData(user); diff --git a/base/common/src/com/netscape/cms/servlet/processors/Processor.java b/base/common/src/com/netscape/cms/servlet/processors/Processor.java index 2349b48ea..5a3b27063 100644 --- a/base/common/src/com/netscape/cms/servlet/processors/Processor.java +++ b/base/common/src/com/netscape/cms/servlet/processors/Processor.java @@ -18,6 +18,7 @@ package com.netscape.cms.servlet.processors; +import java.lang.reflect.Method; import java.math.BigInteger; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; @@ -33,6 +34,7 @@ import java.util.Map.Entry; import java.util.StringTokenizer; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.FormParam; import netscape.security.x509.X509CertImpl; @@ -1260,4 +1262,51 @@ public class Processor { CMS.debug("Processor: Nonce verified"); } + + public String getUserMessage(String messageId, String... params) { + return CMS.getUserMessage(locale, messageId, params); + } + + public void audit(String message, String scope, String type, String id, Map params, String status) { + + if (auditor == null) return; + + String auditMessage = CMS.getLogMessage( + message, + auditor.getSubjectID(), + status, + auditor.getParamString(scope, type, id, params)); + + auditor.log(auditMessage); + } + + /** + * Get the values of the fields annotated with @FormParam. + */ + public Map getParams(Object object) { + + Map map = new HashMap(); + + // for each fields in the object + for (Method method : object.getClass().getMethods()) { + FormParam element = method.getAnnotation(FormParam.class); + if (element == null) continue; + + String name = element.value(); + + try { + // get the value from the object + Object value = method.invoke(object); + + // put the value in the map + map.put(name, value == null ? null : value.toString()); + + } catch (Exception e) { + // ignore inaccessible fields + e.printStackTrace(); + } + } + + return map; + } } diff --git a/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java b/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java index b2c38d808..75eeffd97 100644 --- a/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java @@ -114,7 +114,7 @@ public class GroupCLI extends CLI { } public static void printGroupMember(GroupMemberData groupMemberData) { - System.out.println(" Member: "+groupMemberData.getID()); + System.out.println(" User: "+groupMemberData.getID()); Link link = groupMemberData.getLink(); if (verbose && link != null) { diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserAddMembershipCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserAddMembershipCLI.java new file mode 100644 index 000000000..e1b523ace --- /dev/null +++ b/base/java-tools/src/com/netscape/cmstools/user/UserAddMembershipCLI.java @@ -0,0 +1,57 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cmstools.user; + +import com.netscape.certsrv.user.UserMembershipData; +import com.netscape.cmstools.cli.CLI; +import com.netscape.cmstools.cli.MainCLI; + +/** + * @author Endi S. Dewata + */ +public class UserAddMembershipCLI extends CLI { + + public UserCLI parent; + + public UserAddMembershipCLI(UserCLI parent) { + super("add-membership", "Add user membership"); + this.parent = parent; + } + + public void printHelp() { + formatter.printHelp(parent.name + "-" + name + " [OPTIONS...]", options); + } + + public void execute(String[] args) throws Exception { + + if (args.length != 2) { + printHelp(); + System.exit(1); + } + + String userID = args[0]; + String groupID = args[1]; + + UserMembershipData userMembershipData = parent.client.addUserMembership(userID, groupID); + + MainCLI.printMessage("Added membership in \""+groupID+"\""); + + UserCLI.printUserMembership(userMembershipData); + } +} diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java index 8c24d1746..84dd6bae5 100644 --- a/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java @@ -26,6 +26,7 @@ import org.jboss.resteasy.plugins.providers.atom.Link; import com.netscape.certsrv.user.UserCertData; import com.netscape.certsrv.user.UserClient; import com.netscape.certsrv.user.UserData; +import com.netscape.certsrv.user.UserMembershipData; import com.netscape.cmstools.cli.CLI; import com.netscape.cmstools.cli.MainCLI; @@ -51,6 +52,10 @@ public class UserCLI extends CLI { addModule(new UserShowCertCLI(this)); addModule(new UserAddCertCLI(this)); addModule(new UserRemoveCertCLI(this)); + + addModule(new UserFindMembershipCLI(this)); + addModule(new UserAddMembershipCLI(this)); + addModule(new UserRemoveMembershipCLI(this)); } public void printHelp() { @@ -159,4 +164,13 @@ public class UserCLI extends CLI { System.out.println(encoded); } } + + public static void printUserMembership(UserMembershipData userMembershipData) { + System.out.println(" Group: "+userMembershipData.getID()); + + Link link = userMembershipData.getLink(); + if (verbose && link != null) { + System.out.println(" Link: " + link.getHref()); + } + } } diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserFindMembershipCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserFindMembershipCLI.java new file mode 100644 index 000000000..494c3c323 --- /dev/null +++ b/base/java-tools/src/com/netscape/cmstools/user/UserFindMembershipCLI.java @@ -0,0 +1,104 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cmstools.user; + +import java.util.Collection; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; + +import com.netscape.certsrv.user.UserMembershipCollection; +import com.netscape.certsrv.user.UserMembershipData; +import com.netscape.cmstools.cli.CLI; +import com.netscape.cmstools.cli.MainCLI; + +/** + * @author Endi S. Dewata + */ +public class UserFindMembershipCLI extends CLI { + + public UserCLI parent; + + public UserFindMembershipCLI(UserCLI parent) { + super("find-membership", "Find user memberships"); + this.parent = parent; + } + + public void printHelp() { + formatter.printHelp(parent.name + "-" + name + " [OPTIONS...]", options); + } + + public void execute(String[] args) throws Exception { + + Option option = new Option(null, "start", true, "Page start"); + option.setArgName("start"); + options.addOption(option); + + option = new Option(null, "size", true, "Page size"); + option.setArgName("size"); + options.addOption(option); + + CommandLine cmd = null; + + try { + cmd = parser.parse(options, args); + + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + printHelp(); + System.exit(1); + } + + String[] cmdArgs = cmd.getArgs(); + + if (cmdArgs.length != 1) { + printHelp(); + System.exit(1); + } + + String userID = cmdArgs[0]; + + String s = cmd.getOptionValue("start"); + Integer start = s == null ? null : Integer.valueOf(s); + + s = cmd.getOptionValue("size"); + Integer size = s == null ? null : Integer.valueOf(s); + + UserMembershipCollection response = parent.client.findUserMemberships(userID, start, size); + + Collection entries = response.getMemberships(); + + MainCLI.printMessage(entries.size()+" membership(s) matched"); + + boolean first = true; + + for (UserMembershipData userMembershipData : entries) { + + if (first) { + first = false; + } else { + System.out.println(); + } + + UserCLI.printUserMembership(userMembershipData); + } + + MainCLI.printMessage("Number of entries returned "+entries.size()); + } +} diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserRemoveMembershipCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserRemoveMembershipCLI.java new file mode 100644 index 000000000..cab887a38 --- /dev/null +++ b/base/java-tools/src/com/netscape/cmstools/user/UserRemoveMembershipCLI.java @@ -0,0 +1,54 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2013 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cmstools.user; + +import com.netscape.cmstools.cli.CLI; +import com.netscape.cmstools.cli.MainCLI; + +/** + * @author Endi S. Dewata + */ +public class UserRemoveMembershipCLI extends CLI { + + public UserCLI parent; + + public UserRemoveMembershipCLI(UserCLI parent) { + super("remove-membership", "Remove user membership"); + this.parent = parent; + } + + public void printHelp() { + formatter.printHelp(parent.name + "-" + name + " [OPTIONS...]", options); + } + + public void execute(String[] args) throws Exception { + + if (args.length != 2) { + printHelp(); + System.exit(1); + } + + String userID = args[0]; + String groupID = args[1]; + + parent.client.removeUserMembership(userID, groupID); + + MainCLI.printMessage("Deleted membership in group \""+groupID+"\""); + } +} diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java index 0ed23f697..b205c6a5d 100644 --- a/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java +++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java @@ -12,6 +12,7 @@ import com.netscape.cms.servlet.admin.GroupMemberService; import com.netscape.cms.servlet.admin.GroupService; import com.netscape.cms.servlet.admin.SystemCertService; import com.netscape.cms.servlet.admin.UserCertService; +import com.netscape.cms.servlet.admin.UserMembershipService; import com.netscape.cms.servlet.admin.UserService; import com.netscape.cms.servlet.csadmin.SystemConfigService; import com.netscape.cms.servlet.key.KeyService; @@ -38,6 +39,7 @@ public class KeyRecoveryAuthorityApplication extends Application { classes.add(GroupMemberService.class); classes.add(GroupService.class); classes.add(UserCertService.class); + classes.add(UserMembershipService.class); classes.add(UserService.class); // system certs diff --git a/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java b/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java index 21b37f801..f9995c1a0 100644 --- a/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java +++ b/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java @@ -12,6 +12,7 @@ import com.netscape.cms.servlet.admin.GroupMemberService; import com.netscape.cms.servlet.admin.GroupService; import com.netscape.cms.servlet.admin.SystemCertService; import com.netscape.cms.servlet.admin.UserCertService; +import com.netscape.cms.servlet.admin.UserMembershipService; import com.netscape.cms.servlet.admin.UserService; import com.netscape.cms.servlet.csadmin.SystemConfigService; @@ -32,6 +33,7 @@ public class OCSPApplication extends Application { classes.add(GroupMemberService.class); classes.add(GroupService.class); classes.add(UserCertService.class); + classes.add(UserMembershipService.class); classes.add(UserService.class); // system certs diff --git a/base/tks/src/com/netscape/tks/TKSApplication.java b/base/tks/src/com/netscape/tks/TKSApplication.java index 229a64c95..0939d1cd2 100644 --- a/base/tks/src/com/netscape/tks/TKSApplication.java +++ b/base/tks/src/com/netscape/tks/TKSApplication.java @@ -12,6 +12,7 @@ import com.netscape.cms.servlet.admin.GroupMemberService; import com.netscape.cms.servlet.admin.GroupService; import com.netscape.cms.servlet.admin.SystemCertService; import com.netscape.cms.servlet.admin.UserCertService; +import com.netscape.cms.servlet.admin.UserMembershipService; import com.netscape.cms.servlet.admin.UserService; import com.netscape.cms.servlet.csadmin.SystemConfigService; @@ -32,6 +33,7 @@ public class TKSApplication extends Application { classes.add(GroupMemberService.class); classes.add(GroupService.class); classes.add(UserCertService.class); + classes.add(UserMembershipService.class); classes.add(UserService.class); // system certs -- cgit