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