001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kim.web.struts.action; 017 018import java.sql.Timestamp; 019import java.util.Calendar; 020import java.util.HashMap; 021import java.util.Map; 022 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpServletResponse; 025 026import org.apache.commons.lang.StringUtils; 027import org.apache.struts.action.ActionForm; 028import org.apache.struts.action.ActionForward; 029import org.apache.struts.action.ActionMapping; 030import org.kuali.rice.core.api.membership.MemberType; 031import org.kuali.rice.core.api.util.RiceConstants; 032import org.kuali.rice.core.api.util.RiceKeyConstants; 033import org.kuali.rice.kew.api.exception.WorkflowException; 034import org.kuali.rice.kim.api.KimConstants; 035import org.kuali.rice.kim.api.group.Group; 036import org.kuali.rice.kim.api.identity.principal.Principal; 037import org.kuali.rice.kim.api.role.Role; 038import org.kuali.rice.kim.api.services.KimApiServiceLocator; 039import org.kuali.rice.kim.api.type.KimType; 040import org.kuali.rice.kim.bo.ui.GroupDocumentMember; 041import org.kuali.rice.kim.document.IdentityManagementGroupDocument; 042import org.kuali.rice.kim.rule.event.ui.AddGroupMemberEvent; 043import org.kuali.rice.kim.web.struts.form.IdentityManagementGroupDocumentForm; 044import org.kuali.rice.kns.web.struts.action.KualiTableRenderAction; 045import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 046import org.kuali.rice.kns.web.struts.form.KualiTableRenderFormMetadata; 047import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 048import org.kuali.rice.krad.util.GlobalVariables; 049 050/** 051 * 052 * @author Kuali Rice Team (rice.collab@kuali.org) 053 * 054 */ 055public class IdentityManagementGroupDocumentAction extends IdentityManagementDocumentActionBase implements KualiTableRenderAction { 056 057 /** 058 * This constructs a ... 059 * 060 */ 061 public IdentityManagementGroupDocumentAction() { 062 super(); 063 addMethodToCallToUncheckedList( CHANGE_MEMBER_TYPE_CODE_METHOD_TO_CALL ); 064 addMethodToCallToUncheckedList( CHANGE_NAMESPACE_METHOD_TO_CALL ); 065 } 066 067 /** 068 * This method doesn't actually sort the column - it's just that we need a sort method in 069 * order to exploit the existing methodToCall logic. The sorting is handled in the execute 070 * method below, and delegated to the KualiTableRenderFormMetadata object. 071 * 072 * @param mapping 073 * @param form 074 * @param request 075 * @param response 076 * @return 077 * @throws Exception 078 */ 079 public ActionForward sort(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 080 081 return mapping.findForward(RiceConstants.MAPPING_BASIC); 082 } 083 084 @Override 085 public ActionForward execute(ActionMapping mapping, ActionForm form, 086 HttpServletRequest request, HttpServletResponse response) throws Exception { 087 IdentityManagementGroupDocumentForm groupDocumentForm = (IdentityManagementGroupDocumentForm) form; 088 if ( StringUtils.isBlank( groupDocumentForm.getGroupId() ) ) { 089 String groupId = request.getParameter(KimConstants.PrimaryKeyConstants.GROUP_ID); 090 groupDocumentForm.setGroupId(groupId); 091 } 092 String kimTypeId = request.getParameter(KimConstants.PrimaryKeyConstants.KIM_TYPE_ID); 093 setKimType(kimTypeId, groupDocumentForm); 094 095 096 KualiTableRenderFormMetadata memberTableMetadata = groupDocumentForm.getMemberTableMetadata(); 097 if (groupDocumentForm.getMemberRows() != null) { 098 memberTableMetadata.jumpToPage(memberTableMetadata.getViewedPageNumber(), groupDocumentForm.getMemberRows().size(), groupDocumentForm.getRecordsPerPage()); 099 // KULRICE-3972: need to be able to sort by column header like on lookups when editing large roles and groups 100 memberTableMetadata.sort(groupDocumentForm.getMemberRows(), groupDocumentForm.getRecordsPerPage()); 101 } 102 103 ActionForward forward = super.execute(mapping, groupDocumentForm, request, response); 104 105 groupDocumentForm.setCanAssignGroup(validAssignGroup(groupDocumentForm.getGroupDocument())); 106 return forward; 107 } 108 109 protected void setKimType(String kimTypeId, IdentityManagementGroupDocumentForm groupDocumentForm){ 110 if ( StringUtils.isNotBlank(kimTypeId) ) { 111 KimType kType = KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId); 112 groupDocumentForm.setKimType(kType); 113 if (groupDocumentForm.getGroupDocument() != null) { 114 groupDocumentForm.getGroupDocument().setKimType(kType); 115 } 116 } else if ( groupDocumentForm.getGroupDocument() != null && StringUtils.isNotBlank(groupDocumentForm.getGroupDocument().getGroupTypeId() ) ) { 117 groupDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType( 118 groupDocumentForm.getGroupDocument().getGroupTypeId())); 119 groupDocumentForm.getGroupDocument().setKimType(groupDocumentForm.getKimType()); 120 } 121 } 122 123 /** 124 * This overridden method ... 125 * 126 * @see org.kuali.rice.krad.web.struts.action.KualiDocumentActionBase#loadDocument(org.kuali.rice.krad.web.struts.form.KualiDocumentFormBase) 127 */ 128 @Override 129 protected void loadDocument(KualiDocumentFormBase form) 130 throws WorkflowException { 131 super.loadDocument(form); 132 133 IdentityManagementGroupDocumentForm groupDocumentForm = (IdentityManagementGroupDocumentForm) form; 134 setKimType(groupDocumentForm.getGroupId(), groupDocumentForm); 135 groupDocumentForm.setMember(groupDocumentForm.getGroupDocument().getBlankMember()); 136 137 KualiTableRenderFormMetadata memberTableMetadata = groupDocumentForm.getMemberTableMetadata(); 138 if (groupDocumentForm.getMemberRows() != null) { 139 memberTableMetadata.jumpToFirstPage(groupDocumentForm.getMemberRows().size(), groupDocumentForm.getRecordsPerPage()); 140 } 141 } 142 143 /** 144 * This overridden method ... 145 * 146 * @see org.kuali.rice.krad.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.rice.krad.web.struts.form.KualiDocumentFormBase) 147 */ 148 @Override 149 protected void createDocument(KualiDocumentFormBase form) 150 throws WorkflowException { 151 super.createDocument(form); 152 IdentityManagementGroupDocumentForm groupDocumentForm = (IdentityManagementGroupDocumentForm) form; 153 if ( groupDocumentForm.getGroupId() == null ) { 154 groupDocumentForm.getGroupDocument().setKimType(groupDocumentForm.getKimType()); 155 groupDocumentForm.getGroupDocument().initializeDocumentForNewGroup(); 156 groupDocumentForm.setGroupId( groupDocumentForm.getGroupDocument().getGroupId() ); 157 setKimType(groupDocumentForm.getGroupDocument().getGroupTypeId(), groupDocumentForm); 158 } else { 159 loadGroupIntoDocument( groupDocumentForm.getGroupId(), groupDocumentForm ); 160 } 161 KualiTableRenderFormMetadata memberTableMetadata = groupDocumentForm.getMemberTableMetadata(); 162 if (groupDocumentForm.getMemberRows() != null) { 163 memberTableMetadata.jumpToFirstPage(groupDocumentForm.getMemberRows().size(), groupDocumentForm.getRecordsPerPage()); 164 } 165 } 166 167 168 protected void loadGroupIntoDocument( String groupId, IdentityManagementGroupDocumentForm groupDocumentForm){ 169 Group group = KimApiServiceLocator.getGroupService().getGroup(groupId); 170 getUiDocumentService().loadGroupDoc(groupDocumentForm.getGroupDocument(), group); 171 } 172 173 /*** 174 * @see org.kuali.rice.kim.web.struts.action.IdentityManagementDocumentActionBase#getActionName() 175 */ 176 public String getActionName(){ 177 return KimConstants.KimUIConstants.KIM_GROUP_DOCUMENT_ACTION; 178 } 179 180 protected boolean validAssignGroup(IdentityManagementGroupDocument document){ 181 boolean rulePassed = true; 182 Map<String,String> additionalPermissionDetails = new HashMap<String,String>(); 183 if (!StringUtils.isEmpty(document.getGroupNamespace())) { 184 additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getGroupNamespace()); 185 additionalPermissionDetails.put(KimConstants.AttributeConstants.GROUP_NAME, document.getGroupName()); 186 additionalPermissionDetails.put(KimConstants.AttributeConstants.KIM_TYPE_NAME, document.getKimType().getName()); 187 if (!getDocumentHelperService().getDocumentAuthorizer(document).isAuthorizedByTemplate( 188 document, 189 KimConstants.NAMESPACE_CODE, 190 KimConstants.PermissionTemplateNames.POPULATE_GROUP, 191 GlobalVariables.getUserSession().getPrincipalId(), 192 additionalPermissionDetails, null)){ 193 rulePassed = false; 194 } 195 } 196 return rulePassed; 197 } 198 199 public ActionForward changeMemberTypeCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 200 IdentityManagementGroupDocumentForm groupDocumentForm = (IdentityManagementGroupDocumentForm) form; 201 groupDocumentForm.getMember().setMemberName(""); 202 return refresh(mapping, groupDocumentForm, request, response); 203 } 204 205 public ActionForward addMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 206 IdentityManagementGroupDocumentForm groupDocumentForm = (IdentityManagementGroupDocumentForm) form; 207 GroupDocumentMember newMember = groupDocumentForm.getMember(); 208 209 //See if possible to add with just Group Details filled in (not returned from lookup) 210 if (StringUtils.isEmpty(newMember.getMemberId()) 211 && StringUtils.isNotEmpty(newMember.getMemberName()) 212 && StringUtils.isNotEmpty(newMember.getMemberNamespaceCode()) 213 && StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE.getCode())) { 214 Group tempGroup = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName( 215 newMember.getMemberNamespaceCode(), newMember.getMemberName()); 216 if (tempGroup != null) { 217 newMember.setMemberId(tempGroup.getId()); 218 } 219 } 220 221 //See if possible to grab details for Principal 222 if (StringUtils.isEmpty(newMember.getMemberId()) 223 && StringUtils.isNotEmpty(newMember.getMemberName()) 224 && StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode())) { 225 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(newMember.getMemberName()); 226 if (principal != null) { 227 newMember.setMemberId(principal.getPrincipalId()); 228 } 229 } 230 if(checkKimDocumentGroupMember(newMember) && 231 KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddGroupMemberEvent("", groupDocumentForm.getGroupDocument(), newMember))){ 232 newMember.setDocumentNumber(groupDocumentForm.getDocument().getDocumentNumber()); 233 groupDocumentForm.getGroupDocument().addMember(newMember); 234 groupDocumentForm.setMember(groupDocumentForm.getGroupDocument().getBlankMember()); 235 groupDocumentForm.getMemberTableMetadata().jumpToLastPage(groupDocumentForm.getMemberRows().size(), groupDocumentForm.getRecordsPerPage()); 236 } 237 return mapping.findForward(RiceConstants.MAPPING_BASIC); 238 } 239 240 protected boolean checkKimDocumentGroupMember(GroupDocumentMember newMember){ 241 if(StringUtils.isBlank(newMember.getMemberTypeCode()) || StringUtils.isBlank(newMember.getMemberId())){ 242 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_EMPTY_ENTRY, 243 new String[] {"Member Type Code and Member ID"}); 244 return false; 245 } 246 if(MemberType.PRINCIPAL.getCode().equals(newMember.getMemberTypeCode())){ 247 Principal principalInfo = getIdentityService().getPrincipal(newMember.getMemberId()); 248 if (principalInfo == null) { 249 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 250 new String[] {newMember.getMemberId()}); 251 return false; 252 } 253 else { 254 newMember.setMemberName(principalInfo.getPrincipalName()); 255 } 256 } else if(MemberType.GROUP.getCode().equals(newMember.getMemberTypeCode())){ 257 Group groupInfo = null; 258 groupInfo = KimApiServiceLocator.getGroupService().getGroup(newMember.getMemberId()); 259 if (groupInfo == null) { 260 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 261 new String[] {newMember.getMemberId()}); 262 return false; 263 } 264 else { 265 newMember.setMemberName(groupInfo.getName()); 266 newMember.setMemberNamespaceCode(groupInfo.getNamespaceCode()); 267 } 268 } else if(MemberType.ROLE.getCode().equals(newMember.getMemberTypeCode())){ 269 Role role = KimApiServiceLocator.getRoleService().getRole(newMember.getMemberId()); 270 if (role == null) { 271 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 272 new String[] {newMember.getMemberId()}); 273 return false; 274 } 275 else if(StringUtils.equals(newMember.getMemberTypeCode(), MemberType.ROLE.getCode()) 276 && !validateRole(newMember.getMemberId(), role, "document.member.memberId", "Role")){ 277 return false; 278 } 279 else { 280 newMember.setMemberName(role.getName()); 281 newMember.setMemberNamespaceCode(role.getNamespaceCode()); 282 } 283 } 284 return true; 285 } 286 287 public ActionForward deleteMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 288 IdentityManagementGroupDocumentForm groupDocumentForm = (IdentityManagementGroupDocumentForm) form; 289 GroupDocumentMember memberToBeInactivated = groupDocumentForm.getGroupDocument().getMembers().get(getLineToDelete(request)); 290 Calendar cal = Calendar.getInstance(); 291 memberToBeInactivated.setActiveToDate(new Timestamp(cal.getTimeInMillis())); 292 groupDocumentForm.getGroupDocument().getMembers().set(getLineToDelete(request), memberToBeInactivated); 293 groupDocumentForm.setMember(groupDocumentForm.getGroupDocument().getBlankMember()); 294 return mapping.findForward(RiceConstants.MAPPING_BASIC); 295 } 296 297}