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