Coverage Report - org.kuali.rice.kew.doctype.service.impl.DocumentSecurityServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
DocumentSecurityServiceImpl
0%
0/121
0%
0/78
6.636
 
 1  
 /*
 2  
  * Copyright 2007-2009 The Kuali Foundation
 3  
  * 
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  * 
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  * 
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kew.doctype.service.impl;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.core.api.CoreConstants;
 20  
 import org.kuali.rice.core.api.datetime.DateTimeService;
 21  
 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
 22  
 import org.kuali.rice.core.util.KeyValue;
 23  
 import org.kuali.rice.kew.api.KewApiServiceLocator;
 24  
 import org.kuali.rice.kew.api.document.Document;
 25  
 import org.kuali.rice.kew.docsearch.DocSearchDTO;
 26  
 import org.kuali.rice.kew.doctype.DocumentTypeSecurity;
 27  
 import org.kuali.rice.kew.doctype.SecurityAttribute;
 28  
 import org.kuali.rice.kew.doctype.SecurityPermissionInfo;
 29  
 import org.kuali.rice.kew.doctype.SecuritySession;
 30  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 31  
 import org.kuali.rice.kew.doctype.service.DocumentSecurityService;
 32  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 33  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 34  
 import org.kuali.rice.kew.user.UserUtils;
 35  
 import org.kuali.rice.kew.util.KEWConstants;
 36  
 import org.kuali.rice.kim.api.group.Group;
 37  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 38  
 import org.kuali.rice.kim.bo.Person;
 39  
 import org.kuali.rice.krad.UserSession;
 40  
 
 41  
 import java.lang.reflect.Field;
 42  
 import java.util.Calendar;
 43  
 import java.util.Collection;
 44  
 import java.util.HashMap;
 45  
 import java.util.Iterator;
 46  
 import java.util.List;
 47  
 import java.util.Map;
 48  
 
 49  
 
 50  0
 public class DocumentSecurityServiceImpl implements DocumentSecurityService {
 51  0
   public static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentSecurityServiceImpl.class);
 52  
 
 53  
   @Override
 54  
 public boolean docSearchAuthorized(UserSession userSession, DocSearchDTO docCriteriaDTO, SecuritySession session) {
 55  0
       return checkAuthorization(userSession, session, docCriteriaDTO.getDocTypeName(), docCriteriaDTO.getDocumentId(), docCriteriaDTO.getInitiatorWorkflowId());
 56  
   }
 57  
 
 58  
   @Override
 59  
 public boolean routeLogAuthorized(UserSession userSession, DocumentRouteHeaderValue routeHeader, SecuritySession session) {
 60  0
       return checkAuthorization(userSession, session, routeHeader.getDocumentType().getName(), routeHeader.getDocumentId(), routeHeader.getInitiatorWorkflowId());
 61  
   }
 62  
 
 63  
   protected boolean checkAuthorization(UserSession userSession, SecuritySession session, String documentTypeName, String documentId, String initiatorPrincipalId) {
 64  0
       DocumentTypeSecurity security = null;
 65  
       try {
 66  0
           security = getDocumentTypeSecurity(userSession, documentTypeName, session);
 67  0
           if (security == null || !security.isActive()) {
 68  
             // Security is not enabled for this doctype.  Everyone can see this doc.
 69  0
             return true;
 70  
           }
 71  0
           if (isAdmin(session)) {
 72  0
               return true;
 73  
           }
 74  0
           for (SecurityAttribute securityAttribute : security.getSecurityAttributes()) {
 75  0
               Boolean authorized = securityAttribute.docSearchAuthorized(userSession.getPerson(), documentTypeName, documentId, initiatorPrincipalId);
 76  0
               if (authorized != null) {
 77  0
                   return authorized.booleanValue();
 78  
               }
 79  0
           }
 80  
       } 
 81  0
       catch (Exception e) {
 82  0
           LOG.warn("Not able to retrieve DocumentTypeSecurity from remote system for doctype: " + documentTypeName, e);
 83  0
           return false;
 84  0
       }
 85  0
       return checkStandardAuthorization(security, userSession, documentTypeName, documentId, initiatorPrincipalId, session);
 86  
   }
 87  
 
 88  
   protected boolean isAdmin(SecuritySession session) {
 89  0
           if (session.getUserSession() == null) {
 90  0
                   return false;
 91  
           }
 92  0
           return KimApiServiceLocator.getPermissionService().isAuthorized(session.getUserSession().getPrincipalId(), KEWConstants.KEW_NAMESPACE,        KEWConstants.PermissionNames.UNRESTRICTED_DOCUMENT_SEARCH, new HashMap<String, String>(), new HashMap<String, String>());
 93  
   }
 94  
 
 95  
   protected boolean checkStandardAuthorization(DocumentTypeSecurity security, UserSession userSession, String docTypeName, String documentId, String initiatorPrincipalId, SecuritySession session) {
 96  0
         Person user = userSession.getPerson();
 97  
 
 98  0
     LOG.debug("auth check user=" + user.getPrincipalId() +" docId=" + documentId);
 99  
 
 100  
     // Doc Initiator Authorization
 101  0
     if (security.getInitiatorOk() != null && security.getInitiatorOk()) {
 102  0
       boolean isInitiator = StringUtils.equals(initiatorPrincipalId, user.getPrincipalId());
 103  0
       if (isInitiator) {
 104  0
         return true;
 105  
       }
 106  
     }
 107  
 
 108  
     // Role authorization
 109  
     /* Removing in Rice 1.1
 110  
     List<String> allowedRoles = security.getAllowedRoles();
 111  
     List<String> disallowedRoles = security.getDisallowedRoles();
 112  
     // only execute role security if they have it defined
 113  
     if ((allowedRoles != null && !allowedRoles.isEmpty()) ||
 114  
                     (disallowedRoles != null && !disallowedRoles.isEmpty())) {
 115  
             Boolean passesRoleSecurity = session.getPassesRoleSecurity().get(docTypeName);
 116  
             if (passesRoleSecurity != null) {
 117  
                     if (passesRoleSecurity) {
 118  
                             return true;
 119  
                     }
 120  
             } else {
 121  
                     passesRoleSecurity = isRoleAuthenticated(allowedRoles, disallowedRoles, userSession, session);
 122  
                     session.getPassesRoleSecurity().put(docTypeName, passesRoleSecurity);
 123  
                     if (passesRoleSecurity) {
 124  
                             return true;
 125  
                     }
 126  
             }
 127  
     }
 128  
     */
 129  
     
 130  
     // Permission Authorization
 131  0
     List<SecurityPermissionInfo> securityPermissions = security.getPermissions();
 132  0
     if (securityPermissions != null) {
 133  0
             for (SecurityPermissionInfo securityPermission : securityPermissions) {
 134  0
                     if (isAuthenticatedByPermission(documentId, securityPermission.getPermissionNamespaceCode(), securityPermission.getPermissionName(), securityPermission.getPermissionDetails(), securityPermission.getQualifications(), session)) {
 135  0
                             return true;
 136  
                     }
 137  
             }
 138  
     }
 139  
 
 140  
     //  Workgroup Authorization
 141  0
     List<Group> securityWorkgroups = security.getWorkgroups();
 142  0
     if (securityWorkgroups != null) {
 143  0
       for (Group securityWorkgroup : securityWorkgroups) {
 144  0
         if (isWorkgroupAuthenticated(securityWorkgroup.getNamespaceCode(), securityWorkgroup.getName(), session)) {
 145  0
                 return true;
 146  
         }
 147  
       }
 148  
     }
 149  
 
 150  
     // Searchable Attribute Authorization
 151  0
     Collection searchableAttributes = security.getSearchableAttributes();
 152  0
     if (searchableAttributes != null) {
 153  0
       for (Iterator iterator = searchableAttributes.iterator(); iterator.hasNext();) {
 154  0
         KeyValue searchableAttr = (KeyValue) iterator.next();
 155  0
         String attrName = searchableAttr.getKey();
 156  0
         String idType = searchableAttr.getValue();
 157  0
         String idValue = UserUtils.getIdValue(idType, user);
 158  0
         if (!StringUtils.isEmpty(idValue)) {
 159  0
           if (KEWServiceLocator.getRouteHeaderService().hasSearchableAttributeValue(documentId, attrName, idValue)) {
 160  0
             return true;
 161  
           }
 162  
         }
 163  0
       }
 164  
     }
 165  
 
 166  
     // Route Log Authorization
 167  0
     if (security.getRouteLogAuthenticatedOk() != null && security.getRouteLogAuthenticatedOk()) {
 168  0
       boolean isInitiator = StringUtils.equals(initiatorPrincipalId, user.getPrincipalId());
 169  0
       if (isInitiator) {
 170  0
         return true;
 171  
       }
 172  0
       boolean hasTakenAction = KEWServiceLocator.getActionTakenService().hasUserTakenAction(user.getPrincipalId(), documentId);
 173  0
       if (hasTakenAction) {
 174  0
         return true;
 175  
       }
 176  0
       boolean hasRequest = KEWServiceLocator.getActionRequestService().doesPrincipalHaveRequest(user.getPrincipalId(), documentId);
 177  0
       if (hasRequest) {
 178  0
         return true;
 179  
       }
 180  
     }
 181  
 
 182  0
     LOG.debug("user not authorized");
 183  0
     return false;
 184  
   }
 185  
 
 186  
 protected DocumentTypeSecurity getDocumentTypeSecurity(UserSession userSession, String documentTypeName, SecuritySession session) {
 187  0
       if (session == null) {
 188  0
           session = new SecuritySession(userSession);
 189  
       }
 190  0
           DocumentTypeSecurity security = session.getDocumentTypeSecurity().get(documentTypeName);
 191  0
           if (security == null) {
 192  0
                   DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
 193  0
                   security = docType.getDocumentTypeSecurity();
 194  0
                   session.getDocumentTypeSecurity().put(documentTypeName, security);
 195  
           }
 196  0
           return security;
 197  
   }
 198  
 
 199  
   protected boolean isWorkgroupAuthenticated(String namespace, String workgroupName, SecuritySession session) {
 200  0
           String key = namespace.trim() + KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER + workgroupName.trim();
 201  0
       Boolean existingAuth = session.getAuthenticatedWorkgroups().get(key);
 202  0
           if (existingAuth != null) {
 203  0
                   return existingAuth;
 204  
           }
 205  0
           boolean memberOfGroup = isMemberOfGroupWithName(namespace, workgroupName, session.getUserSession().getPrincipalId());
 206  0
           session.getAuthenticatedWorkgroups().put(key, memberOfGroup);
 207  0
           return memberOfGroup;
 208  
   }
 209  
 
 210  
         private boolean isMemberOfGroupWithName(String namespace, String groupName, String principalId) {
 211  0
                 for (Group group : KimApiServiceLocator.getGroupService().getGroupsForPrincipal(principalId)) {
 212  0
                         if (StringUtils.equals(namespace, group.getNamespaceCode()) && StringUtils.equals(groupName, group.getName())) {
 213  0
                                 return true;
 214  
                         }
 215  
                 }
 216  0
                 return false;
 217  
         }
 218  
 
 219  
         protected boolean isAuthenticatedByPermission(String documentId, String permissionNamespaceCode,
 220  
                         String permissionName, Map<String, String> permissionDetails,
 221  
                         Map<String, String> qualification, SecuritySession session)  {
 222  
                 
 223  
                 Document document;
 224  
                 try {
 225  0
                     document = KewApiServiceLocator.getWorkflowDocumentService().getDocument(documentId);
 226  
                         
 227  0
                         for (String qualificationKey : qualification.keySet()){
 228  0
                                 String qualificationValue = qualification.get(qualificationKey);
 229  0
                                 String replacementValue = getReplacementString(document, qualificationValue);
 230  0
                         qualification.put(qualificationKey, replacementValue);
 231  0
                         }
 232  
                         
 233  0
                         for (String permissionDetailKey : permissionDetails.keySet()){
 234  0
                                 String detailValue = qualification.get(permissionDetailKey);
 235  0
                                 String replacementValue = getReplacementString(document, detailValue);
 236  0
                         qualification.put(permissionDetailKey, replacementValue);
 237  0
                         }
 238  0
                 } catch (Exception e) {
 239  0
                         LOG.error(e.getMessage(), e);
 240  0
                         return false;
 241  0
                 }
 242  0
                 return KimApiServiceLocator.getPermissionService().isAuthorized(session.getUserSession().getPrincipalId(), permissionNamespaceCode, permissionName, permissionDetails, qualification);
 243  
         }
 244  
 
 245  
         private String getReplacementString(Document document, String value) throws Exception {
 246  0
                 String startsWith = "${document.";
 247  0
                 String endsWith = "}";
 248  0
                 if (value.startsWith(startsWith)) {
 249  0
                         int tokenStart = value.indexOf(startsWith);
 250  0
             int tokenEnd = value.indexOf(endsWith, tokenStart + startsWith.length());
 251  0
             if (tokenEnd == -1) {
 252  0
                 throw new RuntimeException("No ending bracket on token in value " +value);
 253  
             }
 254  0
             String token = value.substring(tokenStart + startsWith.length(), tokenEnd);
 255  
                 
 256  0
             return getRouteHeaderVariableValue(document, token);
 257  
                 }
 258  0
                 return value;
 259  
                 
 260  
         }
 261  
         private String getRouteHeaderVariableValue(Document document, String variableName) throws Exception {
 262  0
                 Field field = document.getClass().getDeclaredField(variableName);
 263  0
                 field.setAccessible(true);
 264  0
                 Object fieldValue = field.get(document);
 265  0
                 Class<?> clazzType = field.getType();
 266  0
                 if (clazzType.equals(String.class)) {
 267  0
                         return (String)fieldValue;
 268  0
                 } else if (clazzType.getName().equals("boolean") || clazzType.getName().equals("java.lang.Boolean")) {
 269  0
                         if ((Boolean)fieldValue) {
 270  0
                                 return "Y";
 271  
                         } 
 272  0
                         return "N";
 273  0
                 } else if (clazzType.getName().equals("java.util.Calendar")) {
 274  
                 
 275  0
                         DateTimeService dateTimeService = GlobalResourceLoader.getService(CoreConstants.Services.DATETIME_SERVICE);
 276  0
                         return dateTimeService.toDateString(((Calendar)fieldValue).getTime());
 277  
                 }
 278  0
                 return String.valueOf(fieldValue);
 279  
         }
 280  
 }