001 /* 002 * Copyright 2011 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 */ 016 package org.kuali.kfs.sec.businessobject.lookup; 017 018 import java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.List; 021 import java.util.Map; 022 023 import org.apache.commons.lang.StringUtils; 024 import org.kuali.kfs.sec.SecConstants; 025 import org.kuali.kfs.sec.SecPropertyConstants; 026 import org.kuali.kfs.sec.businessobject.SecurityAttributeMetadata; 027 import org.kuali.kfs.sec.identity.SecKimAttributes; 028 import org.kuali.kfs.sec.service.AccessSecurityService; 029 import org.kuali.kfs.sys.KFSPropertyConstants; 030 import org.kuali.kfs.sys.context.SpringContext; 031 import org.kuali.kfs.sys.service.UniversityDateService; 032 import org.kuali.rice.kim.bo.Person; 033 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 034 import org.kuali.rice.kim.service.PersonService; 035 import org.kuali.rice.kns.bo.BusinessObject; 036 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry; 037 import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl; 038 import org.kuali.rice.kns.service.KNSServiceLocator; 039 import org.kuali.rice.kns.util.FieldUtils; 040 import org.kuali.rice.kns.util.KNSConstants; 041 import org.kuali.rice.kns.web.format.Formatter; 042 import org.kuali.rice.kns.web.ui.Column; 043 import org.kuali.rice.kns.web.ui.Row; 044 045 046 /** 047 * Calls the access security service to simulate validation for the specified user, attribute, and action 048 */ 049 public class AccessSecuritySimulationLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl { 050 protected AccessSecurityService accessSecurityService; 051 protected UniversityDateService universityDateService; 052 053 protected List<Row> rows; 054 055 public AccessSecuritySimulationLookupableHelperServiceImpl() { 056 rows = null; 057 } 058 059 /** 060 * @see org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl#getSearchResults(java.util.Map) 061 */ 062 @Override 063 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) { 064 String principalName = fieldValues.get(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 065 Person person = SpringContext.getBean(PersonService.class).getPersonByPrincipalName(principalName); 066 067 String attributeName = fieldValues.get(SecPropertyConstants.ATTRIBUTE_NAME); 068 String templateId = fieldValues.get(SecPropertyConstants.TEMPLATE_ID); 069 070 AttributeSet additionalPermissionDetails = new AttributeSet(); 071 if (accessSecurityService.getInquiryWithFieldValueTemplateId().equals(templateId)) { 072 String namespaceCode = fieldValues.get(SecPropertyConstants.INQUIRY_NAMESPACE_CODE); 073 additionalPermissionDetails.put(SecKimAttributes.NAMESPACE_CODE, namespaceCode); 074 } 075 else if (!accessSecurityService.getLookupWithFieldValueTemplateId().equals(templateId)) { 076 String documentTypeCode = fieldValues.get(SecPropertyConstants.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE); 077 additionalPermissionDetails.put(SecKimAttributes.DOCUMENT_TYPE_NAME, documentTypeCode); 078 } 079 080 return runSimulation(person, attributeName, templateId, additionalPermissionDetails); 081 } 082 083 /** 084 * @param person 085 * @param attribute 086 * @param templateId 087 * @param additionalPermissionDetails 088 * @return 089 */ 090 protected List<? extends BusinessObject> runSimulation(Person person, String attributeName, String templateId, AttributeSet additionalPermissionDetails) { 091 List<BusinessObject> resultRecords = new ArrayList<BusinessObject>(); 092 093 if (!SecConstants.ATTRIBUTE_SIMULATION_MAP.containsKey(attributeName)) { 094 throw new RuntimeException("Unable to find attribute metadata for attribute: " + attributeName); 095 } 096 SecurityAttributeMetadata attributeMetadata = SecConstants.ATTRIBUTE_SIMULATION_MAP.get(attributeName); 097 Class attributeClass = attributeMetadata.getAttributeClass(); 098 099 // build criteria for retrieving attribute records 100 Map<String, Object> searchCriteria = new HashMap<String, Object>(); 101 List<String> fieldNames = getPersistenceStructureService().listFieldNames(attributeClass); 102 if (fieldNames.contains(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR)) { 103 searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityDateService.getCurrentFiscalYear()); 104 } 105 106 if (fieldNames.contains(KFSPropertyConstants.ACTIVE)) { 107 searchCriteria.put(KFSPropertyConstants.ACTIVE, true); 108 } 109 110 // retrieve records for this attribute to iterate over and call security service 111 List allAttributeData = (List) getBusinessObjectService().findMatching(attributeClass, searchCriteria); 112 accessSecurityService.applySecurityRestrictions(allAttributeData, person, templateId, additionalPermissionDetails); 113 114 // iterate through business object instances and construct simulation info result objects 115 // for (Iterator iterator = allAttributeData.iterator(); iterator.hasNext();) { 116 // BusinessObject businessObject = (BusinessObject) iterator.next(); 117 // 118 // AccessSecuritySimulation securitySimulation = new AccessSecuritySimulation(); 119 // 120 // Object boKeyFieldValue = ObjectUtils.getPropertyValue(businessObject, attributeMetadata.getAttributeField()); 121 // Object boNameFieldValue = ObjectUtils.getPropertyValue(businessObject, attributeMetadata.getAttributeNameField()); 122 // 123 // securitySimulation.setAttributeValue(boKeyFieldValue.toString()); 124 // securitySimulation.setAttributeValueName(boNameFieldValue.toString()); 125 // 126 // resultRecords.add(securitySimulation); 127 // } 128 129 return allAttributeData; 130 } 131 132 /** 133 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#setRows() 134 */ 135 @Override 136 protected void setRows() { 137 List<String> lookupFieldAttributeList = new ArrayList<String>(); 138 if (getParameters().containsKey(SecPropertyConstants.TEMPLATE_ID)) { 139 String templateId = ((String[]) getParameters().get(SecPropertyConstants.TEMPLATE_ID))[0]; 140 141 if (accessSecurityService.getInquiryWithFieldValueTemplateId().equals(templateId)) { 142 lookupFieldAttributeList = getInquiryTemplateFields(); 143 } 144 else if (accessSecurityService.getLookupWithFieldValueTemplateId().equals(templateId)) { 145 lookupFieldAttributeList = getLookupTemplateFields(); 146 } 147 else { 148 lookupFieldAttributeList = getDocumentTemplateFields(); 149 } 150 } 151 else { 152 lookupFieldAttributeList = getLookupTemplateFields(); 153 } 154 155 // construct field object for each search attribute 156 List fields = new ArrayList(); 157 int numCols; 158 try { 159 fields = FieldUtils.createAndPopulateFieldsForLookup(lookupFieldAttributeList, getReadOnlyFieldsList(), getBusinessObjectClass()); 160 161 BusinessObjectEntry boe = KNSServiceLocator.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(this.getBusinessObjectClass().getName()); 162 numCols = boe.getLookupDefinition().getNumOfColumns(); 163 164 } 165 catch (InstantiationException e) { 166 throw new RuntimeException("Unable to create instance of business object class" + e.getMessage()); 167 } 168 catch (IllegalAccessException e) { 169 throw new RuntimeException("Unable to create instance of business object class" + e.getMessage()); 170 } 171 172 if (numCols == 0) 173 numCols = KNSConstants.DEFAULT_NUM_OF_COLUMNS; 174 175 rows = FieldUtils.wrapFields(fields, numCols); 176 } 177 178 /** 179 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getRows() 180 */ 181 @Override 182 public List<Row> getRows() { 183 return rows; 184 } 185 186 /** 187 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getColumns() 188 */ 189 @Override 190 public List<Column> getColumns() { 191 String searchAttributeName = ((String[]) getParameters().get(SecPropertyConstants.ATTRIBUTE_NAME))[0]; 192 193 SecurityAttributeMetadata attributeMetadata = SecConstants.ATTRIBUTE_SIMULATION_MAP.get(searchAttributeName); 194 Class attributeClass = attributeMetadata.getAttributeClass(); 195 196 ArrayList<Column> columns = new ArrayList<Column>(); 197 for (String attributeName : getBusinessObjectDictionaryService().getLookupResultFieldNames(attributeClass)) { 198 Column column = new Column(); 199 column.setPropertyName(attributeName); 200 201 String columnTitle = getDataDictionaryService().getAttributeLabel(attributeClass, attributeName); 202 Boolean useShortLabel = getBusinessObjectDictionaryService().getLookupResultFieldUseShortLabel(attributeClass, attributeName); 203 if (useShortLabel != null && useShortLabel) { 204 columnTitle = getDataDictionaryService().getAttributeShortLabel(attributeClass, attributeName); 205 } 206 if (StringUtils.isBlank(columnTitle)) { 207 columnTitle = getDataDictionaryService().getCollectionLabel(attributeClass, attributeName); 208 } 209 column.setColumnTitle(columnTitle); 210 211 Integer fieldDefinedMaxLength = getBusinessObjectDictionaryService().getLookupResultFieldMaxLength(attributeClass, attributeName); 212 if (fieldDefinedMaxLength == null) { 213 try { 214 fieldDefinedMaxLength = Integer.valueOf(getParameterService().getParameterValue(KNSConstants.KNS_NAMESPACE, KNSConstants.DetailTypes.LOOKUP_PARM_DETAIL_TYPE, KNSConstants.RESULTS_DEFAULT_MAX_COLUMN_LENGTH)); 215 } 216 catch (NumberFormatException ex) { 217 LOG.error("Lookup field max length parameter not found and unable to parse default set in system parameters (RESULTS_DEFAULT_MAX_COLUMN_LENGTH)."); 218 } 219 } 220 column.setMaxLength(fieldDefinedMaxLength.intValue()); 221 222 Class formatterClass = getDataDictionaryService().getAttributeFormatter(attributeClass, attributeName); 223 if (formatterClass != null) { 224 try { 225 column.setFormatter((Formatter) formatterClass.newInstance()); 226 } 227 catch (InstantiationException e) { 228 LOG.error("Unable to get new instance of formatter class: " + formatterClass.getName()); 229 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName()); 230 } 231 catch (IllegalAccessException e) { 232 LOG.error("Unable to get new instance of formatter class: " + formatterClass.getName()); 233 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName()); 234 } 235 } 236 237 columns.add(column); 238 } 239 240 return columns; 241 } 242 243 /** 244 * Builds List of search field names for searching the inquiry template 245 * 246 * @return List<String> containing lookup field names 247 */ 248 protected List<String> getInquiryTemplateFields() { 249 List<String> lookupFields = new ArrayList<String>(); 250 251 lookupFields.add(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 252 lookupFields.add(SecPropertyConstants.ATTRIBUTE_NAME); 253 lookupFields.add(SecPropertyConstants.TEMPLATE_ID); 254 lookupFields.add(SecPropertyConstants.INQUIRY_NAMESPACE_CODE); 255 256 return lookupFields; 257 } 258 259 /** 260 * Builds List of search field names for searching the lookup template 261 * 262 * @return List<String> containing lookup field names 263 */ 264 protected List<String> getLookupTemplateFields() { 265 List<String> lookupFields = new ArrayList<String>(); 266 267 lookupFields.add(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 268 lookupFields.add(SecPropertyConstants.ATTRIBUTE_NAME); 269 lookupFields.add(SecPropertyConstants.TEMPLATE_ID); 270 271 return lookupFields; 272 } 273 274 /** 275 * Builds List of search field names for searching document templates 276 * 277 * @return List<String> containing lookup field names 278 */ 279 protected List<String> getDocumentTemplateFields() { 280 List<String> lookupFields = new ArrayList<String>(); 281 282 lookupFields.add(SecPropertyConstants.SECURITY_PERSON_PRINCIPAL_NAME); 283 lookupFields.add(SecPropertyConstants.ATTRIBUTE_NAME); 284 lookupFields.add(SecPropertyConstants.TEMPLATE_ID); 285 lookupFields.add(SecPropertyConstants.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE); 286 287 return lookupFields; 288 } 289 290 /** 291 * Sets the accessSecurityService attribute value. 292 * 293 * @param accessSecurityService The accessSecurityService to set. 294 */ 295 public void setAccessSecurityService(AccessSecurityService accessSecurityService) { 296 this.accessSecurityService = accessSecurityService; 297 } 298 299 /** 300 * Sets the universityDateService attribute value. 301 * 302 * @param universityDateService The universityDateService to set. 303 */ 304 public void setUniversityDateService(UniversityDateService universityDateService) { 305 this.universityDateService = universityDateService; 306 } 307 308 }