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.kew.role.service.impl;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
020import org.kuali.rice.core.api.membership.MemberType;
021import org.kuali.rice.kew.api.KewApiServiceLocator;
022import org.kuali.rice.kew.api.document.WorkflowDocumentService;
023import org.kuali.rice.kim.api.KimConstants;
024import org.kuali.rice.kim.api.role.Role;
025import org.kuali.rice.kim.api.role.RoleMembership;
026import org.kuali.rice.kim.framework.common.delegate.DelegationTypeService;
027import org.kuali.rice.kim.framework.role.RoleTypeService;
028import org.kuali.rice.kns.kim.role.DerivedRoleTypeServiceBase;
029
030import java.util.ArrayList;
031import java.util.List;
032import java.util.Map;
033
034/**
035 * 
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 *
038 */
039public class RouteLogDerivedRoleTypeServiceImpl extends DerivedRoleTypeServiceBase implements RoleTypeService, DelegationTypeService {
040    public static final String INITIATOR_ROLE_NAME = "Initiator";
041    public static final String INITIATOR_OR_REVIEWER_ROLE_NAME = "Initiator or Reviewer";
042    public static final String ROUTER_ROLE_NAME = "Router";
043
044    @Override
045    protected boolean isCheckRequiredAttributes() {
046        return true;
047    }
048        
049        /**
050         *      - qualifier is document number
051         *      - the roles that will be of this type are KR-WKFLW Initiator and KR-WKFLW Initiator or Reviewer, KR-WKFLW Router
052         *      - only the initiator of the document in question gets the KR-WKFLW Initiator role
053         *      - user who routed the document according to the route log should get the KR-WKFLW Router role
054         *      - users who are authorized by the route log, 
055         *              i.e. initiators, people who have taken action, people with a pending action request, 
056         *              or people who will receive an action request for the document in question get the KR-WKFLW Initiator or Reviewer Role 
057         *
058         */
059        @Override
060    public List<RoleMembership> getRoleMembersFromDerivedRole(String namespaceCode, String roleName, Map<String, String> qualification) {
061            if (StringUtils.isBlank(namespaceCode)) {
062            throw new RiceIllegalArgumentException("namespaceCode was null or blank");
063        }
064
065        if (roleName == null) {
066            throw new RiceIllegalArgumentException("roleName was null");
067        }
068
069        validateRequiredAttributesAgainstReceived(qualification);
070                List<RoleMembership> members = new ArrayList<RoleMembership>();
071                if(qualification!=null && !qualification.isEmpty()){
072                        String documentId = qualification.get(KimConstants.AttributeConstants.DOCUMENT_NUMBER);
073                        if (StringUtils.isNotBlank(documentId)) {
074                                try{
075                    WorkflowDocumentService workflowDocumentService = KewApiServiceLocator.getWorkflowDocumentService();
076                                        if (INITIATOR_ROLE_NAME.equals(roleName)) {
077                                            String principalId = KewApiServiceLocator.getWorkflowDocumentService().getDocumentInitiatorPrincipalId(
078                                documentId);
079                        RoleMembership roleMembership = RoleMembership.Builder.create(null,null,principalId, MemberType.PRINCIPAL, null).build();
080                            members.add(roleMembership);
081                                        } else if(INITIATOR_OR_REVIEWER_ROLE_NAME.equals(roleName)) {
082                                            List<String> ids = KewApiServiceLocator.getWorkflowDocumentActionsService().getPrincipalIdsInRouteLog(
083                                documentId, true);
084                                            for ( String id : ids ) {
085                                                if ( StringUtils.isNotBlank(id) ) {
086                                RoleMembership roleMembership = RoleMembership.Builder.create(null,null,id, MemberType.PRINCIPAL, null).build();
087                                                        members.add(roleMembership );
088                                                }
089                                            }
090                                        } else if(ROUTER_ROLE_NAME.equals(roleName)) {
091                        String principalId = workflowDocumentService.getRoutedByPrincipalIdByDocumentId(documentId);
092                        RoleMembership roleMembership = RoleMembership.Builder.create(null,null,principalId, MemberType.PRINCIPAL, null).build();
093                            members.add(roleMembership);
094                                        }
095                                } catch(Exception wex){
096                                        throw new RuntimeException(
097                                        "Error in getting principal Ids in route log for document id: "+ documentId +" :"+wex.getLocalizedMessage(),wex);
098                                }
099                        }
100                }
101
102                return members;
103        }
104
105        @Override
106        public boolean hasDerivedRole(
107                        String principalId, List<String> groupIds, String namespaceCode, String roleName, Map<String, String> qualification){
108                if (StringUtils.isBlank(principalId)) {
109            throw new RiceIllegalArgumentException("principalId was null or blank");
110        }
111
112        if (groupIds == null) {
113            throw new RiceIllegalArgumentException("groupIds was null or blank");
114        }
115
116        if (StringUtils.isBlank(namespaceCode)) {
117            throw new RiceIllegalArgumentException("namespaceCode was null or blank");
118        }
119
120        if (StringUtils.isBlank(roleName)) {
121            throw new RiceIllegalArgumentException("roleName was null or blank");
122        }
123
124        if (qualification == null) {
125            throw new RiceIllegalArgumentException("qualification was null");
126        }
127
128
129        validateRequiredAttributesAgainstReceived(qualification);
130        boolean isUserInRouteLog = false;
131                if(qualification!=null && !qualification.isEmpty()){
132                        String documentId = qualification.get(KimConstants.AttributeConstants.DOCUMENT_NUMBER);
133            WorkflowDocumentService workflowDocumentService = KewApiServiceLocator.getWorkflowDocumentService();
134                        try {
135                                if (INITIATOR_ROLE_NAME.equals(roleName)){
136                                        isUserInRouteLog = principalId.equals(workflowDocumentService.getDocumentInitiatorPrincipalId(documentId));
137                                } else if(INITIATOR_OR_REVIEWER_ROLE_NAME.equals(roleName)){
138                                        isUserInRouteLog = KewApiServiceLocator.getWorkflowDocumentActionsService().isUserInRouteLog(
139                            documentId, principalId, true);
140                                } else if(ROUTER_ROLE_NAME.equals(roleName)){
141                                        isUserInRouteLog = principalId.equals(workflowDocumentService.getRoutedByPrincipalIdByDocumentId(
142                            documentId));
143                                }
144                        } catch (Exception wex) {
145                                throw new RuntimeException("Error in determining whether the principal Id: " + principalId + " is in route log " +
146                                                "for document id: " + documentId + " :"+wex.getLocalizedMessage(),wex);
147                        }
148                }
149                return isUserInRouteLog;
150        }
151
152        /**
153     * Determines if the role specified by the given namespace and role name has a dynamic role membership.
154         * Returns true, as the Route Log changes often enough that role membership is highly volatile
155         * 
156         * @see RoleTypeService#dynamicRoleMembership(String, String) dynamicRoleMembership(java.lang.String, java.lang.String)
157         */
158        @Override
159        public boolean dynamicRoleMembership(String namespaceCode, String roleName) {
160                if (StringUtils.isBlank(namespaceCode)) {
161            throw new RiceIllegalArgumentException("namespaceCode was null or blank");
162        }
163
164            if (StringUtils.isBlank(roleName)) {
165            throw new RiceIllegalArgumentException("roleName was null or blank");
166        }
167
168        return true;
169        }
170}