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