001/** 002 * Copyright 2005-2017 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.ArrayList; 020import java.util.Arrays; 021import java.util.Calendar; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import javax.servlet.http.HttpServletRequest; 027import javax.servlet.http.HttpServletResponse; 028 029import org.apache.commons.lang.StringUtils; 030import org.apache.struts.action.ActionForm; 031import org.apache.struts.action.ActionForward; 032import org.apache.struts.action.ActionMapping; 033import org.kuali.rice.core.api.delegation.DelegationType; 034import org.kuali.rice.core.api.membership.MemberType; 035import org.kuali.rice.core.api.util.RiceConstants; 036import org.kuali.rice.core.api.util.RiceKeyConstants; 037import org.kuali.rice.kew.api.exception.WorkflowException; 038import org.kuali.rice.kim.api.KimConstants; 039import org.kuali.rice.kim.api.group.Group; 040import org.kuali.rice.kim.api.identity.Person; 041import org.kuali.rice.kim.api.identity.principal.Principal; 042import org.kuali.rice.kim.api.role.Role; 043import org.kuali.rice.kim.api.services.KimApiServiceLocator; 044import org.kuali.rice.kim.bo.ui.KimDocumentRoleMember; 045import org.kuali.rice.kim.bo.ui.KimDocumentRolePermission; 046import org.kuali.rice.kim.bo.ui.KimDocumentRoleQualifier; 047import org.kuali.rice.kim.bo.ui.KimDocumentRoleResponsibility; 048import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMember; 049import org.kuali.rice.kim.bo.ui.RoleDocumentDelegationMemberQualifier; 050import org.kuali.rice.kim.document.IdentityManagementRoleDocument; 051import org.kuali.rice.kim.impl.responsibility.AddResponsibilityEvent; 052import org.kuali.rice.kim.impl.responsibility.ResponsibilityBo; 053import org.kuali.rice.kim.impl.type.KimTypeLookupableHelperServiceImpl; 054import org.kuali.rice.kim.rule.event.ui.AddDelegationMemberEvent; 055import org.kuali.rice.kim.rule.event.ui.AddMemberEvent; 056import org.kuali.rice.kim.rule.event.ui.AddPermissionEvent; 057import org.kuali.rice.kim.web.struts.form.IdentityManagementRoleDocumentForm; 058import org.kuali.rice.kns.question.ConfirmationQuestion; 059import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 060import org.kuali.rice.kns.web.struts.form.KualiTableRenderFormMetadata; 061import org.kuali.rice.krad.data.KradDataServiceLocator; 062import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 063import org.kuali.rice.krad.util.GlobalVariables; 064import org.kuali.rice.krad.util.KRADConstants; 065 066/** 067 * @author Kuali Rice Team (rice.collab@kuali.org) 068 */ 069public class IdentityManagementRoleDocumentAction extends IdentityManagementDocumentActionBase { 070 071 public static final String CHANGE_DEL_ROLE_MEMBER_METHOD_TO_CALL = "changeDelegationRoleMember"; 072 public static final String SWITCH_TO_ROLE_MEMBER_METHOD_TO_CALL = "jumpToRoleMember"; 073 public static final String REMOVE_AFFECTED_DELEGATES_QUESTION_ID = "RemoveAffectedDelegates"; 074 075 protected List<String> methodToCallToUncheckedList = new ArrayList<String>(); 076 077 /** 078 * This method doesn't actually sort the column - it's just that we need a sort method in 079 * order to exploit the existing methodToCall logic. The sorting is handled in the execute 080 * method below, and delegated to the KualiTableRenderFormMetadata object. 081 * 082 * @param mapping 083 * @param form 084 * @param request 085 * @param response 086 * @return 087 * @throws Exception 088 */ 089 { 090 methodToCallToUncheckedList.add(CHANGE_DEL_ROLE_MEMBER_METHOD_TO_CALL); 091 methodToCallToUncheckedList.add(CHANGE_MEMBER_TYPE_CODE_METHOD_TO_CALL); 092 methodToCallToUncheckedList.add(CHANGE_NAMESPACE_METHOD_TO_CALL); 093 methodToCallToUncheckedList.add(SWITCH_TO_ROLE_MEMBER_METHOD_TO_CALL); 094 } 095 096 /** 097 * This constructs a ... 098 */ 099 public IdentityManagementRoleDocumentAction() { 100 super(); 101 for (String methodToCallToUncheck : methodToCallToUncheckedList) { 102 addMethodToCallToUncheckedList(methodToCallToUncheck); 103 } 104 } 105 106 public ActionForward sort(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 107 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 108 KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata(); 109 memberTableMetadata.setSwitchToPageNumber(0); 110 return mapping.findForward(RiceConstants.MAPPING_BASIC); 111 } 112 113 @Override 114 public ActionForward execute(ActionMapping mapping, ActionForm form, 115 HttpServletRequest request, HttpServletResponse response) throws Exception { 116 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 117 if (roleDocumentForm.getRoleId() == null) { 118 String roleId = request.getParameter(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID); 119 roleDocumentForm.setRoleId(roleId); 120 } 121 String kimTypeId = request.getParameter(KimConstants.PrimaryKeyConstants.KIM_TYPE_ID); 122 setKimType(kimTypeId, roleDocumentForm); 123 124 KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata(); 125 if (roleDocumentForm.getRoleDocument()!=null && roleDocumentForm.getMemberRows() != null) { 126 memberTableMetadata.jumpToPage(memberTableMetadata.getViewedPageNumber(), roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage()); 127 // KULRICE-3972: need to be able to sort by column header like on lookups when editing large roles and groups 128 memberTableMetadata.sort(roleDocumentForm.getMemberRows(), roleDocumentForm.getRecordsPerPage()); 129 } 130 131 // KULRICE-4762: active delegates of "inactivated" role members cause validation problems 132 ActionForward forward = promptForAffectedDelegates(mapping, form, request, response, 133 roleDocumentForm); 134 // if we need to prompt the user due to affected delegates, do so: 135 if (forward != null) { return forward; } 136 137 forward = super.execute(mapping, roleDocumentForm, request, response); 138 139 roleDocumentForm.setCanAssignRole(validAssignRole(roleDocumentForm.getRoleDocument())); 140 if (KimTypeLookupableHelperServiceImpl.hasDerivedRoleTypeService(roleDocumentForm.getRoleDocument().getKimType())) { 141 roleDocumentForm.setCanModifyAssignees(false); 142 } 143 GlobalVariables.getUserSession().addObject(KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_SHORT_KEY, roleDocumentForm.getRoleDocument()); 144 return forward; 145 } 146 147 /** 148 * This overridden method ... 149 * 150 * @see org.kuali.rice.krad.web.struts.action.KualiDocumentActionBase#loadDocument(org.kuali.rice.krad.web.struts.form.KualiDocumentFormBase) 151 */ 152 @Override 153 protected void loadDocument(KualiDocumentFormBase form) 154 throws WorkflowException { 155 super.loadDocument(form); 156 157 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 158 setKimType(roleDocumentForm.getRoleDocument().getRoleTypeId(), roleDocumentForm); 159 160 getUiDocumentService().setDelegationMembersInDocument(roleDocumentForm.getRoleDocument()); 161 getUiDocumentService().setMembersInDocument(roleDocumentForm.getRoleDocument()); 162 163 roleDocumentForm.setMember(roleDocumentForm.getRoleDocument().getBlankMember()); 164 roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember()); 165 166 KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata(); 167 if (roleDocumentForm.getMemberRows() != null) { 168 memberTableMetadata.jumpToFirstPage(roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage()); 169 } 170 } 171 172 @Override 173 protected void createDocument(KualiDocumentFormBase form) 174 throws WorkflowException { 175 super.createDocument(form); 176 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 177 178 if (roleDocumentForm.getRoleId() == null) { 179 roleDocumentForm.getRoleDocument().setKimType(roleDocumentForm.getKimType()); 180 roleDocumentForm.getRoleDocument().initializeDocumentForNewRole(); 181 roleDocumentForm.setRoleId(roleDocumentForm.getRoleDocument().getRoleId()); 182 //roleDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(roleDocumentForm.getRoleDocument().getRoleTypeId())); 183 } else { 184 loadRoleIntoDocument(roleDocumentForm.getRoleId(), roleDocumentForm); 185 } 186 187 roleDocumentForm.setMember(roleDocumentForm.getRoleDocument().getBlankMember()); 188 roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember()); 189 190 KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata(); 191 if (roleDocumentForm.getMemberRows() != null) { 192 memberTableMetadata.jumpToFirstPage(roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage()); 193 } 194 } 195 196 protected void setKimType(String kimTypeId, IdentityManagementRoleDocumentForm roleDocumentForm) { 197 if (StringUtils.isNotBlank(kimTypeId)) { 198 roleDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId)); 199 if (roleDocumentForm.getRoleDocument() != null) { 200 roleDocumentForm.getRoleDocument().setKimType(roleDocumentForm.getKimType()); 201 } 202 } else if (roleDocumentForm.getRoleDocument() != null && StringUtils.isNotBlank(roleDocumentForm.getRoleDocument().getRoleTypeId())) { 203 roleDocumentForm.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType( 204 roleDocumentForm.getRoleDocument().getRoleTypeId())); 205 roleDocumentForm.getRoleDocument().setKimType(roleDocumentForm.getKimType()); 206 } 207 } 208 209 protected void loadRoleIntoDocument(String roleId, IdentityManagementRoleDocumentForm roleDocumentForm) { 210 Role role = KimApiServiceLocator.getRoleService().getRole(roleId); 211 roleDocumentForm.getRoleDocument().setMemberMetaDataTypeToSort(roleDocumentForm.getMemberTableMetadata().getColumnToSortIndex()); 212 getUiDocumentService().loadRoleDoc(roleDocumentForm.getRoleDocument(), role); 213 } 214 215 /** 216 * @see org.kuali.rice.kim.web.struts.action.IdentityManagementDocumentActionBase#getActionName() 217 */ 218 @Override 219 public String getActionName() { 220 return KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_ACTION; 221 } 222 223 protected boolean validAssignRole(IdentityManagementRoleDocument document) { 224 boolean rulePassed = true; 225 if (StringUtils.isNotEmpty(document.getRoleNamespace())) { 226 Map<String, String> additionalPermissionDetails = new HashMap<String, String>(); 227 additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, document.getRoleNamespace()); 228 additionalPermissionDetails.put(KimConstants.AttributeConstants.ROLE_NAME, document.getRoleName()); 229 if (!getDocumentHelperService().getDocumentAuthorizer(document).isAuthorizedByTemplate( 230 document, 231 KimConstants.NAMESPACE_CODE, 232 KimConstants.PermissionTemplateNames.ASSIGN_ROLE, 233 GlobalVariables.getUserSession().getPrincipalId(), 234 additionalPermissionDetails, null)) { 235 rulePassed = false; 236 } 237 } 238 return rulePassed; 239 } 240 241 public ActionForward changeMemberTypeCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 242 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 243 roleDocumentForm.getMember().setMemberId(""); 244 return refresh(mapping, roleDocumentForm, request, response); 245 } 246 247 public ActionForward changeDelegationMemberTypeCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 248 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 249 KimDocumentRoleMember roleMember = roleDocumentForm.getRoleDocument().getMember(roleDocumentForm.getDelegationMember().getRoleMemberId()); 250 if (roleMember != null) { 251 RoleDocumentDelegationMemberQualifier delegationMemberQualifier; 252 for (KimDocumentRoleQualifier roleQualifier : roleMember.getQualifiers()) { 253 delegationMemberQualifier = roleDocumentForm.getDelegationMember().getQualifier(roleQualifier.getKimAttrDefnId()); 254 delegationMemberQualifier.setAttrVal(roleQualifier.getAttrVal()); 255 } 256 } 257 return refresh(mapping, roleDocumentForm, request, response); 258 } 259 260 public ActionForward addResponsibility(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 261 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 262 KimDocumentRoleResponsibility newResponsibility = roleDocumentForm.getResponsibility(); 263 if (newResponsibility != null && StringUtils.isNotBlank(newResponsibility.getResponsibilityId())) { 264 ResponsibilityBo responsibilityImpl = KradDataServiceLocator.getDataObjectService().find(ResponsibilityBo.class, newResponsibility.getResponsibilityId()); 265 newResponsibility.setKimResponsibility(responsibilityImpl); 266 } 267 268 if (KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddResponsibilityEvent("", roleDocumentForm.getRoleDocument(), newResponsibility))) { 269 if (newResponsibility != null) { 270 newResponsibility.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber()); 271 } 272 roleDocumentForm.getRoleDocument().addResponsibility(newResponsibility); 273 roleDocumentForm.setResponsibility(new KimDocumentRoleResponsibility()); 274 roleDocumentForm.getRoleDocument().updateMembers(newResponsibility); 275 } 276 return mapping.findForward(RiceConstants.MAPPING_BASIC); 277 } 278 279 public ActionForward deleteResponsibility(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 280 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 281 roleDocumentForm.getRoleDocument().getResponsibilities().remove(getLineToDelete(request)); 282 roleDocumentForm.getRoleDocument().updateMembers(roleDocumentForm); 283 return mapping.findForward(RiceConstants.MAPPING_BASIC); 284 } 285 286 public ActionForward addPermission(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 287 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 288 KimDocumentRolePermission newPermission = roleDocumentForm.getPermission(); 289 if (KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddPermissionEvent("", roleDocumentForm.getRoleDocument(), newPermission))) { 290 newPermission.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber()); 291 newPermission.setRoleId(roleDocumentForm.getRoleDocument().getRoleId()); 292 roleDocumentForm.getRoleDocument().getPermissions().add(newPermission); 293 roleDocumentForm.setPermission(new KimDocumentRolePermission()); 294 } 295 return mapping.findForward(RiceConstants.MAPPING_BASIC); 296 } 297 298 public ActionForward addMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 299 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 300 KimDocumentRoleMember newMember = roleDocumentForm.getMember(); 301 302 //See if possible to add with just Group Details filled in (not returned from lookup) 303 if ( StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE.getCode()) 304 && StringUtils.isEmpty(newMember.getMemberId()) 305 && !newMember.isMemberNameNull() 306 && !newMember.isMemberNameSpaceCodeNull() ) { 307 Group tempGroup = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName( 308 newMember.getMemberNamespaceCode(), newMember.getMemberName()); 309 if (tempGroup != null) { 310 newMember.setMemberId(tempGroup.getId()); 311 } 312 } 313 314 //See if possible to grab details for Principal 315 if ( StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode()) 316 && StringUtils.isEmpty(newMember.getMemberId()) 317 && StringUtils.isNotEmpty(newMember.getMemberName())) { 318 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(newMember.getMemberName()); 319 if (principal != null) { 320 newMember.setMemberId(principal.getPrincipalId()); 321 String fullName = checkMemberFullName(principal.getPrincipalId()); 322 if (fullName != null) { 323 newMember.setMemberFullName(fullName); 324 } 325 } 326 } else if ( StringUtils.equals(newMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode()) 327 && StringUtils.isNotEmpty(newMember.getMemberId()) 328 && StringUtils.isNotEmpty(newMember.getMemberName())) { 329 String fullName = checkMemberFullName(newMember.getMemberId()); 330 if (fullName != null) { 331 newMember.setMemberFullName(fullName); 332 } 333 } 334 335 if (checkKimDocumentRoleMember(newMember) && 336 KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddMemberEvent("", roleDocumentForm.getRoleDocument(), newMember))) { 337 newMember.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber()); 338 roleDocumentForm.getRoleDocument().addMember(newMember); 339 roleDocumentForm.setMember(roleDocumentForm.getRoleDocument().getBlankMember()); 340 } 341 return mapping.findForward(RiceConstants.MAPPING_BASIC); 342 } 343 344 protected String checkMemberFullName(String principalId) { 345 Principal principal = getIdentityService().getPrincipal(principalId); 346 if (principal != null) { 347 Person psn = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principal.getPrincipalName()); 348 if (psn != null) { 349 return psn.getFirstName() + " " + psn.getLastName(); 350 } 351 } 352 return null; 353 } 354 355 protected boolean checkKimDocumentRoleMember(KimDocumentRoleMember newMember) { 356 boolean memberExists = false; 357 String memberName = null; 358 String memberNamespace = null; 359 360 if (StringUtils.isBlank(newMember.getMemberId())) { 361 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_EMPTY_ENTRY, 362 new String[]{"Member ID"}); 363 return false; 364 } 365 366 if (MemberType.PRINCIPAL.getCode().equals(newMember.getMemberTypeCode())) { 367 Principal pi = this.getIdentityService().getPrincipal(newMember.getMemberId()); 368 if (pi != null) { 369 memberExists = true; 370 memberName = pi.getPrincipalName(); 371 memberNamespace = ""; 372 } 373 } else if (MemberType.GROUP.getCode().equals(newMember.getMemberTypeCode())) { 374 Group gi = KimApiServiceLocator.getGroupService().getGroup(newMember.getMemberId()); 375 if (gi != null) { 376 memberExists = true; 377 memberName = gi.getName(); 378 memberNamespace = gi.getNamespaceCode(); 379 } 380 } else if (MemberType.ROLE.getCode().equals(newMember.getMemberTypeCode())) { 381 Role ri = KimApiServiceLocator.getRoleService().getRole(newMember.getMemberId()); 382 if (!validateRole(newMember.getMemberId(), ri, "document.member.memberId", "Role")) { 383 return false; 384 } else { 385 memberExists = true; 386 memberName = ri.getName(); 387 memberNamespace = ri.getNamespaceCode(); 388 } 389 } 390 391 if (!memberExists) { 392 GlobalVariables.getMessageMap().putError("document.member.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 393 new String[]{newMember.getMemberId()}); 394 return false; 395 } 396 newMember.setMemberName(memberName); 397 newMember.setMemberNamespaceCode(memberNamespace); 398 return true; 399 } 400 401 public ActionForward deleteMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 402 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 403 KimDocumentRoleMember inactivatedRoleMember = roleDocumentForm.getRoleDocument().getModifiedMembers().get(getLineToDelete(request)); 404 405 // KULRICE-4762: active delegates of "inactivated" role members cause validation problems 406 ActionForward forward = promptForAffectedDelegates(mapping, form, request, response, 407 roleDocumentForm, /* we haven't actually inactivated them yet, so specify them here */ inactivatedRoleMember); 408 // if we need to prompt the user due to affected delegates, do so: 409 if (forward != null) { 410 return forward; 411 } 412 413 Calendar cal = Calendar.getInstance(); 414 inactivatedRoleMember.setActiveToDate(new Timestamp(cal.getTimeInMillis())); 415 416 roleDocumentForm.getRoleDocument().getModifiedMembers().set(getLineToDelete(request), inactivatedRoleMember); 417 return mapping.findForward(RiceConstants.MAPPING_BASIC); 418 } 419 420 public ActionForward editMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 421 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 422 KimDocumentRoleMember roleMemberToEdit = roleDocumentForm.getRoleDocument().getMembers().get(getLineToEdit(request)); 423 KimDocumentRoleMember copiedMember = KradDataServiceLocator.getDataObjectService().copyInstance(roleMemberToEdit); 424 roleDocumentForm.getRoleDocument().getModifiedMembers().add(copiedMember); 425 roleDocumentForm.getRoleDocument().getMembers().remove(roleMemberToEdit); 426 return mapping.findForward(RiceConstants.MAPPING_BASIC); 427 } 428 429 public ActionForward editSearchResultsMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 430 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 431 KimDocumentRoleMember roleMemberToEdit = roleDocumentForm.getRoleDocument().getSearchResultMembers().get(getLineToEdit(request)); 432 KimDocumentRoleMember copiedMember = KradDataServiceLocator.getDataObjectService().copyInstance(roleMemberToEdit); 433 roleDocumentForm.getRoleDocument().getModifiedMembers().add(copiedMember); 434 roleDocumentForm.getRoleDocument().getSearchResultMembers().remove(roleMemberToEdit); 435 roleDocumentForm.getRoleDocument().getMembers().remove(roleMemberToEdit); 436 return mapping.findForward(RiceConstants.MAPPING_BASIC); 437 } 438 439 public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 440 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 441 String memberSearchValue = roleDocumentForm.getMemberSearchValue(); 442 if (memberSearchValue != null && !memberSearchValue.isEmpty()) { 443 memberSearchValue = memberSearchValue.replaceAll("[%*]",""); 444 getUiDocumentService().loadRoleMembersBasedOnSearch(roleDocumentForm.getRoleDocument(), memberSearchValue); 445 } else { 446 clear(mapping, form, request, response); 447 } 448 return mapping.findForward(RiceConstants.MAPPING_BASIC); 449 } 450 451 public ActionForward clear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 452 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 453 roleDocumentForm.setMemberSearchValue(""); 454 getUiDocumentService().clearRestrictedRoleMembersSearchResults(roleDocumentForm.getRoleDocument()); 455 456 KualiTableRenderFormMetadata memberTableMetadata = roleDocumentForm.getMemberTableMetadata(); 457 if (roleDocumentForm.getMemberRows() != null) { 458 memberTableMetadata.jumpToFirstPage(roleDocumentForm.getMemberRows().size(), roleDocumentForm.getRecordsPerPage()); 459 } 460 return mapping.findForward(RiceConstants.MAPPING_BASIC); 461 } 462 463 public ActionForward deletePermission(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 464 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 465 roleDocumentForm.getRoleDocument().getPermissions().remove(getLineToDelete(request)); 466 return mapping.findForward(RiceConstants.MAPPING_BASIC); 467 } 468 469 protected boolean checkDelegationMember(RoleDocumentDelegationMember newMember) { 470 if (StringUtils.isBlank(newMember.getMemberTypeCode()) || StringUtils.isBlank(newMember.getMemberId())) { 471 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_EMPTY_ENTRY, 472 new String[]{"Member Type Code and Member ID"}); 473 return false; 474 } 475 if (MemberType.PRINCIPAL.getCode().equals(newMember.getMemberTypeCode())) { 476 Principal principalInfo = getIdentityService().getPrincipal(newMember.getMemberId()); 477 if (principalInfo == null) { 478 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 479 new String[]{newMember.getMemberId()}); 480 return false; 481 } else { 482 newMember.setMemberName(principalInfo.getPrincipalName()); 483 } 484 } else if (MemberType.GROUP.getCode().equals(newMember.getMemberTypeCode())) { 485 Group groupInfo = null; 486 groupInfo = getGroupService().getGroup(newMember.getMemberId()); 487 if (groupInfo == null) { 488 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 489 new String[]{newMember.getMemberId()}); 490 return false; 491 } else { 492 newMember.setMemberName(groupInfo.getName()); 493 newMember.setMemberNamespaceCode(groupInfo.getNamespaceCode()); 494 } 495 } else if (MemberType.ROLE.getCode().equals(newMember.getMemberTypeCode())) { 496 Role roleInfo = KimApiServiceLocator.getRoleService().getRole(newMember.getMemberId()); 497 if (roleInfo == null) { 498 GlobalVariables.getMessageMap().putError("document.delegationMember.memberId", RiceKeyConstants.ERROR_MEMBERID_MEMBERTYPE_MISMATCH, 499 new String[]{newMember.getMemberId()}); 500 return false; 501 } else { 502 newMember.setMemberName(roleInfo.getName()); 503 newMember.setMemberNamespaceCode(roleInfo.getNamespaceCode()); 504 } 505 } 506 return true; 507 } 508 509 public ActionForward addDelegationMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 510 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 511 RoleDocumentDelegationMember newDelegationMember = roleDocumentForm.getDelegationMember(); 512 513 //See if possible to add with just Group Details filled in (not returned from lookup) 514 if (StringUtils.isEmpty(newDelegationMember.getMemberId()) 515 && StringUtils.isNotEmpty(newDelegationMember.getMemberName()) 516 && StringUtils.isNotEmpty(newDelegationMember.getMemberNamespaceCode()) 517 && StringUtils.equals(newDelegationMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE.getCode())) { 518 Group tempGroup = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName( 519 newDelegationMember.getMemberNamespaceCode(), newDelegationMember.getMemberName()); 520 if (tempGroup != null) { 521 newDelegationMember.setMemberId(tempGroup.getId()); 522 } 523 } 524 525 //See if possible to grab details for Principal 526 if (StringUtils.isEmpty(newDelegationMember.getMemberId()) 527 && StringUtils.isNotEmpty(newDelegationMember.getMemberName()) 528 && StringUtils.equals(newDelegationMember.getMemberTypeCode(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode())) { 529 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(newDelegationMember.getMemberName()); 530 if (principal != null) { 531 newDelegationMember.setMemberId(principal.getPrincipalId()); 532 } 533 } 534 535 if (checkDelegationMember(newDelegationMember) && KRADServiceLocatorWeb.getKualiRuleService().applyRules( 536 new AddDelegationMemberEvent("", roleDocumentForm.getRoleDocument(), newDelegationMember))) { 537 newDelegationMember.setDocumentNumber(roleDocumentForm.getDocument().getDocumentNumber()); 538 if (StringUtils.isEmpty(newDelegationMember.getDelegationTypeCode())) { 539 newDelegationMember.setDelegationTypeCode(DelegationType.SECONDARY.getCode()); 540 } 541 roleDocumentForm.getRoleDocument().addDelegationMember(newDelegationMember); 542 roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember()); 543 } 544 return mapping.findForward(RiceConstants.MAPPING_BASIC); 545 } 546 547 public ActionForward deleteDelegationMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 548 IdentityManagementRoleDocumentForm roleDocumentForm = (IdentityManagementRoleDocumentForm) form; 549 550 RoleDocumentDelegationMember memberToDelete = roleDocumentForm.getRoleDocument().getDelegationMembers().get(getLineToDelete(request)); 551 // if it's a new member that hasn't been saved yet, just allow them to delete it, otherwise inactivate it 552 if (memberToDelete.getDelegationMemberId() == null) { 553 roleDocumentForm.getRoleDocument().getDelegationMembers().remove(getLineToDelete(request)); 554 } else { 555 Calendar cal = Calendar.getInstance(); 556 memberToDelete.setActiveToDate(new Timestamp(cal.getTimeInMillis())); 557 } 558 559 roleDocumentForm.setDelegationMember(roleDocumentForm.getRoleDocument().getBlankDelegationMember()); 560 return mapping.findForward(RiceConstants.MAPPING_BASIC); 561 } 562 563 /** 564 * @see org.kuali.rice.kns.web.struts.action.KualiTableRenderAction#switchToPage(org.apache.struts.action.ActionMapping, 565 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 566 */ 567 public ActionForward jumpToRoleMember(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 568 IdentityManagementRoleDocumentForm idmForm = (IdentityManagementRoleDocumentForm) form; 569 String delegationRoleMemberId = getDelegationRoleMemberToJumpTo(request); 570 KualiTableRenderFormMetadata memberTableMetadata = idmForm.getMemberTableMetadata(); 571 memberTableMetadata.jumpToPage(idmForm.getPageNumberOfRoleMemberId(delegationRoleMemberId), 572 idmForm.getMemberRows().size(), idmForm.getRecordsPerPage()); 573 memberTableMetadata.setColumnToSortIndex(memberTableMetadata.getPreviouslySortedColumnIndex()); 574 idmForm.setAnchor(delegationRoleMemberId); 575 return mapping.findForward(RiceConstants.MAPPING_BASIC); 576 } 577 578 protected String getDelegationRoleMemberToJumpTo(HttpServletRequest request) { 579 String delegationRoleMemberIdToJumpTo = ""; 580 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 581 if (StringUtils.isNotBlank(parameterName)) { 582 delegationRoleMemberIdToJumpTo = StringUtils.substringBetween(parameterName, ".dmrmi", "."); 583 } 584 return delegationRoleMemberIdToJumpTo; 585 } 586 587 588 /** 589 * Side-effecting method returns an ActionForward if needed for handling prompting of the user about automatically 590 * "inactivating" active delegates of inactive role members. If the user has already responded "Yes", delegates are 591 * "inactivated" here, and a null forward is returned. Otherwise, an appropriate forward is returned. 592 * 593 * @param roleMembersToConsiderInactive additional role members to consider inactive for the purposes of this computation 594 */ 595 private ActionForward promptForAffectedDelegates(ActionMapping mapping, 596 ActionForm form, HttpServletRequest request, 597 HttpServletResponse response, 598 IdentityManagementRoleDocumentForm roleDocumentForm, KimDocumentRoleMember... roleMembersToConsiderInactive) 599 throws Exception { 600 // KULRICE-4762: Role: Removed an Assignee who has delegations associated with him and now the Role cannot be updated 601 // To solve this issue, prompt for confirmation if there are active delegates for the role member being "inactivated", 602 // and upon confirmation, "inactivate" the delegates too. 603 List<RoleDocumentDelegationMember> activeDelegatesOfInactiveRoleMembers = 604 getActiveDelegatesOfInactiveRoleMembers(roleDocumentForm, roleMembersToConsiderInactive); 605 ActionForward forward = getAffectedDelegatesQuestionActionForward(activeDelegatesOfInactiveRoleMembers, mapping, form, request, 606 response, roleDocumentForm); 607 // if the question logic gave us a forward, do it 608 if (forward != null) { 609 return forward; 610 } 611 // otherwise, inactivate affected delegates 612 if (activeDelegatesOfInactiveRoleMembers.size() > 0) { 613 Calendar cal = Calendar.getInstance(); 614 // deactivate (inactivate?) delegates 615 for (RoleDocumentDelegationMember delegateToDeactivate : activeDelegatesOfInactiveRoleMembers) { 616 delegateToDeactivate.setActiveToDate(new Timestamp(cal.getTimeInMillis())); 617 } 618 } 619 return null; 620 } 621 622 /** 623 * <p>If there are active delegates of an "inactivated" role member, return an ActionForward to prompt the user 624 * letting them know that the delegates will be "inactivated" too if they proceed. 625 * <p>Also, if the user has already responded to the question and the response was (1) "Yes", then return null, signifying 626 * that we can go ahead and take the needed action to "inactivate" the delegates; or (2) "No", then return a basic forward that 627 * will cancel further action. 628 */ 629 private ActionForward getAffectedDelegatesQuestionActionForward(List<RoleDocumentDelegationMember> activeDelegatesOfInactiveRoleMembers, 630 ActionMapping mapping, ActionForm form, HttpServletRequest request, 631 HttpServletResponse response, 632 IdentityManagementRoleDocumentForm roleDocumentForm) 633 throws Exception { 634 635 if (activeDelegatesOfInactiveRoleMembers.size() > 0) { 636 Object question = getQuestion(request); 637 // logic for delegates question 638 if (question == null || !REMOVE_AFFECTED_DELEGATES_QUESTION_ID.equals(question)) { 639 return performQuestionWithoutInput(mapping, form, request, response, REMOVE_AFFECTED_DELEGATES_QUESTION_ID, 640 getKualiConfigurationService().getPropertyValueAsString( 641 RiceKeyConstants.QUESTION_ACTIVE_DELEGATES_FOR_INACTIVE_MEMBERS), 642 KRADConstants.CONFIRMATION_QUESTION, roleDocumentForm.getMethodToCall(), StringUtils.EMPTY); 643 } 644 Object buttonClicked = request.getParameter(KRADConstants.QUESTION_CLICKED_BUTTON); 645 if ((REMOVE_AFFECTED_DELEGATES_QUESTION_ID.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) { 646 // the question was answered in the affirmative. 647 // fall through, no special mapping to return 648 } else { 649 // NO was clicked ... what to do? Return basic mapping without "inactivating" anything 650 return mapping.findForward(RiceConstants.MAPPING_BASIC); 651 } 652 } 653 654 return null; 655 } 656 657 /** 658 * This method returns a list of all active delegates for role members that are inactive 659 * 660 * @param roleDocumentForm form bean 661 * @param roleMembersToConsiderInactive additional role members to consider inactive for the purposes of this computation 662 * @return the active delegates of inactive role members 663 */ 664 private List<RoleDocumentDelegationMember> getActiveDelegatesOfInactiveRoleMembers( 665 IdentityManagementRoleDocumentForm roleDocumentForm, KimDocumentRoleMember... roleMembersToConsiderInactive) { 666 List<KimDocumentRoleMember> roleMembers = roleDocumentForm.getMemberRows(); 667 List<KimDocumentRoleMember> inactiveRoleMembers = new ArrayList<KimDocumentRoleMember>(); 668 List<RoleDocumentDelegationMember> activeDelegatesOfInactivatedRoleMembers = new ArrayList<RoleDocumentDelegationMember>(); 669 670 inactiveRoleMembers.addAll(Arrays.asList(roleMembersToConsiderInactive)); 671 672 if (roleMembers != null) { 673 for (KimDocumentRoleMember roleMember : roleMembers) { 674 if (roleMember != null) { 675 if (!roleMember.isActive()) { 676 inactiveRoleMembers.add(roleMember); 677 } 678 } 679 } 680 } 681 682 for (KimDocumentRoleMember inactiveRoleMember : inactiveRoleMembers) { 683 // check if there are delegates for the member being removed 684 List<RoleDocumentDelegationMember> delegationMembers = roleDocumentForm.getRoleDocument().getDelegationMembers(); 685 if (delegationMembers != null) { 686 for (RoleDocumentDelegationMember delegationMember : delegationMembers) { 687 if (delegationMember != null && delegationMember.isActive()) { 688 // if the roleMember for this delegation is the same as the inactivatedRoleMember 689 if (delegationMember.getRoleMemberId().equals(inactiveRoleMember.getRoleMemberId())) { 690 activeDelegatesOfInactivatedRoleMembers.add(delegationMember); 691 } 692 } 693 } 694 } 695 } 696 return activeDelegatesOfInactivatedRoleMembers; 697 } 698 699 /** 700 * This method overrides validateRole() from IdentityManagementDocumentActionBase. 701 * The difference with this method is that it allows derived roles. 702 * The base implementation returns false if the role is a derived role. 703 * 704 */ 705 @Override 706 protected boolean validateRole(String roleId, Role role, String propertyName, String message) { 707 if (role == null) { 708 GlobalVariables.getMessageMap().putError(propertyName, RiceKeyConstants.ERROR_INVALID_ROLE, roleId); 709 return false; 710 } 711 return true; 712 } 713 714 715}