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 }