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