2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 package org.collectionspace.services.report.nuxeo;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileOutputStream;
30 import java.io.InputStream;
31 import java.nio.file.Files;
32 import java.sql.Connection;
33 import java.sql.SQLException;
34 import java.util.HashMap;
35 import java.util.List;
37 import java.util.regex.Pattern;
39 import javax.ws.rs.core.MediaType;
40 import javax.naming.NamingException;
41 import javax.ws.rs.core.Response;
43 import net.sf.jasperreports.engine.JRException;
44 import net.sf.jasperreports.engine.JRExporter;
45 import net.sf.jasperreports.engine.JRExporterParameter;
46 import net.sf.jasperreports.engine.JRParameter;
47 import net.sf.jasperreports.engine.JasperCompileManager;
48 import net.sf.jasperreports.engine.JasperFillManager;
49 import net.sf.jasperreports.engine.JasperPrint;
50 import net.sf.jasperreports.engine.design.JasperDesign;
51 import net.sf.jasperreports.engine.export.JRCsvExporter;
52 import net.sf.jasperreports.engine.export.JRCsvExporterParameter;
53 import net.sf.jasperreports.engine.export.JRHtmlExporter;
54 import net.sf.jasperreports.engine.export.JRPdfExporter;
55 import net.sf.jasperreports.engine.export.JRXmlExporter;
56 import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
57 import net.sf.jasperreports.engine.export.ooxml.JRPptxExporter;
58 import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
59 import net.sf.jasperreports.engine.xml.JRXmlLoader;
61 import org.collectionspace.authentication.AuthN;
62 import org.collectionspace.services.ReportJAXBSchema;
63 import org.collectionspace.services.account.AccountResource;
64 import org.collectionspace.services.authorization.AuthZ;
65 import org.collectionspace.services.authorization.CSpaceResource;
66 import org.collectionspace.services.authorization.PermissionException;
67 import org.collectionspace.services.authorization.URIResourceImpl;
68 import org.collectionspace.services.authorization.perms.ActionType;
69 import org.collectionspace.services.report.ResourceActionGroup;
70 import org.collectionspace.services.report.ResourceActionGroupList;
71 import org.collectionspace.services.report.ReportsCommon.ForRoles;
72 import org.collectionspace.services.report.MIMEType;
73 import org.collectionspace.services.report.MIMETypeItemType;
74 import org.collectionspace.services.report.ReportResource;
75 import org.collectionspace.services.report.ReportsCommon;
76 import org.collectionspace.services.report.ReportsOuputMimeList;
77 import org.collectionspace.services.client.PoxPayloadIn;
78 import org.collectionspace.services.client.PoxPayloadOut;
79 import org.collectionspace.services.client.ReportClient;
80 import org.collectionspace.services.common.CSWebApplicationException;
81 import org.collectionspace.services.common.ServiceMain;
82 import org.collectionspace.services.common.api.JEEServerDeployment;
83 import org.collectionspace.services.common.api.FileTools;
84 import org.collectionspace.services.common.api.Tools;
85 import org.collectionspace.services.common.authorization_mgt.ActionGroup;
86 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
87 import org.collectionspace.services.common.context.ServiceBindingUtils;
88 import org.collectionspace.services.common.context.ServiceContext;
89 import org.collectionspace.services.common.document.BadRequestException;
90 import org.collectionspace.services.common.document.DocumentException;
91 import org.collectionspace.services.common.document.DocumentWrapper;
92 import org.collectionspace.services.common.invocable.Invocable;
93 import org.collectionspace.services.common.invocable.InvocationContext;
94 import org.collectionspace.services.common.storage.JDBCTools;
95 import org.collectionspace.services.config.service.ServiceBindingType;
96 import org.collectionspace.services.config.types.PropertyItemType;
97 import org.collectionspace.services.jaxb.InvocableJAXBSchema;
98 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
99 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
100 import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl;
101 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
103 import org.jfree.util.Log;
105 import org.nuxeo.ecm.core.api.model.PropertyException;
106 import org.nuxeo.ecm.core.api.DocumentModel;
108 import org.slf4j.Logger;
109 import org.slf4j.LoggerFactory;
112 * ReportDocumentModelHandler
114 * $LastChangedRevision: $
115 * $LastChangedDate: $
117 public class ReportDocumentModelHandler extends NuxeoDocumentModelHandler<ReportsCommon> {
118 private final Logger logger = LoggerFactory.getLogger(ReportDocumentModelHandler.class);
120 private static final Pattern INVALID_CSID_PATTERN = Pattern.compile("[^\\w\\-]");
121 private static String CSID_LIST_SEPARATOR = ",";
123 private static String REPORTS_STD_CSID_PARAM = "csid";
124 private static String REPORTS_STD_GROUPCSID_PARAM = "groupcsid";
125 private static String REPORTS_STD_CSIDLIST_PARAM = "csidlist";
126 private static String REPORTS_STD_TENANTID_PARAM = "tenantid";
129 // Map the MIME types from the service bindings to our payload output
131 public ReportsOuputMimeList getSupportMIMETypes(
132 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
134 // Create a new payload response instance and initialize it
136 ReportsOuputMimeList result = new ReportsOuputMimeList();
137 MIMEType resultMIMEType = result.getMIMETypeList();
138 if (resultMIMEType == null) {
139 result.setMIMETypeList(resultMIMEType = new MIMEType());
141 List<MIMETypeItemType> resultMIMETypeItemList = resultMIMEType.getMIMEType();
144 // Read the MIME type values from the service bindings and put into our response payload
146 TenantBindingConfigReaderImpl tReader =
147 ServiceMain.getInstance().getTenantBindingConfigReader();
148 ServiceBindingType reportServiceBinding = tReader.getServiceBinding(ctx.getTenantId(), ctx.getServiceName());
149 List<PropertyItemType> bindingsMIMETypeList = ServiceBindingUtils.getPropertyValueList(reportServiceBinding, ServiceBindingUtils.OUTPUT_MIME_PROP);
151 if (bindingsMIMETypeList != null) {
152 for (PropertyItemType bindingItemMimeType : bindingsMIMETypeList) {
153 MIMETypeItemType resultMimeTypeItem = new MIMETypeItemType();
154 String displayName = bindingItemMimeType.getDisplayName();
155 if (displayName != null && displayName.trim().isEmpty() == false) {
156 resultMimeTypeItem.setKey(displayName);
158 resultMimeTypeItem.setKey(bindingItemMimeType.getValue());
160 resultMimeTypeItem.setValue(bindingItemMimeType.getValue());
161 resultMIMETypeItemList.add(resultMimeTypeItem);
168 private String getInvocationContextLogging(InvocationContext invContext, Map<String, Object> params) {
169 String outputMIME = invContext.getOutputMIME();
170 String mode = invContext.getMode();
171 String updateCoreValues = invContext.getUpdateCoreValues();
172 String docType = invContext.getDocType();
173 String singleCSID = invContext.getSingleCSID();
174 String groupCSID = invContext.getGroupCSID();
175 String listCSIDs = invContext.getListCSIDs() == null ? "" : invContext.getListCSIDs().toString();
178 "{MIME type: " + outputMIME +
179 "\n \t Context mode: " + mode +
180 "\n \t Update Core Values: " + updateCoreValues +
181 "\n \t Document type: " + docType +
182 "\n \t CSID: " + singleCSID +
183 "\n \t Group CSID: " + groupCSID +
184 "\n \t List CSIDs: " + listCSIDs +
185 "\n \t Parameters: " + params.toString() + "}";
189 private String assertValidCsid(String csid) throws IllegalArgumentException {
190 if (INVALID_CSID_PATTERN.matcher(csid).find()) {
191 throw new IllegalArgumentException("Invalid csid: " + csid);
197 public InputStream invokeReport(
198 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
200 ReportsCommon reportsCommon,
201 InvocationContext invContext,
202 StringBuffer outMimeType,
203 StringBuffer outReportFileName) throws Exception {
204 CoreSessionInterface repoSession = null;
205 boolean releaseRepoSession = false;
207 // Ensure the current user has permission to run this report
208 if (isAuthoritzed(reportsCommon) == false) {
209 String msg = String.format("Report Resource: The user '%s' is not authorized to run the report '%s' CSID='%s'",
210 AuthN.get().getUserId(), reportsCommon.getName(), csid);
211 throw new PermissionException(msg);
214 String invocationMode = invContext.getMode();
215 String modeProperty = null;
216 HashMap<String, Object> params = new HashMap<String, Object>();
217 params.put(REPORTS_STD_TENANTID_PARAM, ctx.getTenantId());
218 boolean checkDocType = true;
220 // Note we set before we put in the default ones, so they cannot override tenant or CSID.
221 setParamsFromContext(params, invContext);
223 if (Invocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {
224 modeProperty = InvocableJAXBSchema.SUPPORTS_SINGLE_DOC;
225 params.put(REPORTS_STD_CSID_PARAM, assertValidCsid(invContext.getSingleCSID()));
226 } else if (Invocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {
227 modeProperty = InvocableJAXBSchema.SUPPORTS_DOC_LIST;
228 List<String> csids = null;
229 InvocationContext.ListCSIDs listThing = invContext.getListCSIDs();
230 if (listThing!=null) {
231 csids = listThing.getCsid();
233 if (csids==null||csids.isEmpty()){
234 throw new BadRequestException(
235 "ReportResource: Report invoked in list mode, with no csids in list." );
237 StringBuilder sb = new StringBuilder();
238 boolean first = true;
239 for(String csidItem : csids) {
243 sb.append(CSID_LIST_SEPARATOR);
244 sb.append(assertValidCsid(csidItem));
246 params.put(REPORTS_STD_CSIDLIST_PARAM, sb.toString());
247 } else if(Invocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {
248 modeProperty = InvocableJAXBSchema.SUPPORTS_GROUP;
249 params.put(REPORTS_STD_GROUPCSID_PARAM, assertValidCsid(invContext.getGroupCSID()));
250 } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {
251 modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;
252 checkDocType = false;
254 throw new BadRequestException("ReportResource: unknown Invocation Mode: "
258 logger.debug("The invocation context is: \n " + getInvocationContextLogging(invContext, params));
259 logger.debug("The report is being called with the following parameters, which are being passed to Jasper: \n" + params.toString());
260 logger.debug("The mode being passed to Jasper is: " + invocationMode);
262 NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx);
263 repoSession = this.getRepositorySession();
264 if (repoSession == null) {
265 repoSession = repoClient.getRepositorySession(ctx);
266 releaseRepoSession = true;
269 // Get properties from the report docModel, and release the session
270 String reportFileNameProperty;
272 DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, csid);
273 DocumentModel docModel = wrapper.getWrappedObject();
274 Boolean supports = (Boolean) NuxeoUtils.getProperyValue(docModel, modeProperty); //docModel.getPropertyValue(modeProperty);
275 if(supports == null || !supports) {
276 throw new BadRequestException(
277 "ReportResource: This Report does not support Invocation Mode: "
281 List<String> forDocTypeList =
282 (List<String>) NuxeoUtils.getProperyValue(docModel, InvocableJAXBSchema.FOR_DOC_TYPES); //docModel.getPropertyValue(InvocableJAXBSchema.FOR_DOC_TYPES);
283 if (forDocTypeList==null || !forDocTypeList.contains(invContext.getDocType())) {
284 throw new BadRequestException(
285 "ReportResource: Invoked with unsupported document type: "
286 +invContext.getDocType());
289 reportFileNameProperty = (String) NuxeoUtils.getProperyValue(docModel, ReportJAXBSchema.FILENAME); //docModel.getPropertyValue(ReportJAXBSchema.FILENAME)); // Set the outgoing param with the report file name
291 // If the invocation context contains a MIME type then use it. Otherwise, look in the report resource. If no MIME type in the report resource,
292 // use the default MIME type.
294 if (!Tools.isEmpty(invContext.getOutputMIME())) {
295 outMimeType.append(invContext.getOutputMIME());
296 } else if (Tools.isEmpty(outMimeType.toString()) && params.containsKey("OutputMIME")) {
297 // See UCB - https://github.com/cspace-deployment/services/pull/140/files
298 outMimeType.append(params.get("OutputMIME"));
301 String reportOutputMime = (String) NuxeoUtils.getProperyValue(docModel, ReportJAXBSchema.OUTPUT_MIME); //docModel.getPropertyValue(ReportJAXBSchema.OUTPUT_MIME);
302 if (!Tools.isEmpty(reportOutputMime)) {
303 outMimeType.append(reportOutputMime);
305 outMimeType.append(ReportClient.DEFAULT_REPORT_OUTPUT_MIME);
308 } catch (PropertyException pe) {
309 if (logger.isDebugEnabled()) {
310 logger.debug("Property exception getting report values: ", pe);
313 } catch (DocumentException de) {
314 if (logger.isDebugEnabled()) {
315 logger.debug("Problem getting report report: ", de);
318 } catch (Exception e) {
319 if (logger.isDebugEnabled()) {
320 logger.debug("Caught exception ", e);
322 throw new DocumentException(e);
324 if (releaseRepoSession && repoSession != null) {
325 repoClient.releaseRepositorySession(ctx, repoSession);
329 return buildReportResult(csid, params, reportFileNameProperty, outMimeType.toString(), outReportFileName);
332 private void setParamsFromContext(Map<String, Object> params, InvocationContext invContext) {
333 InvocationContext.Params icParams = invContext.getParams();
334 if(icParams!= null) {
335 List<InvocationContext.Params.Param> icParamList = icParams.getParam();
336 if(icParamList != null) {
337 for(InvocationContext.Params.Param param:icParamList) {
338 String key = param.getKey();
339 String value = param.getValue();
340 if(!Tools.isEmpty(key) && !Tools.isEmpty(value)) {
341 params.put(key, value);
349 private InputStream buildReportResult(
351 HashMap<String, Object> params,
352 String reportFileName,
353 String outputMimeType,
354 StringBuffer outReportFileName
357 Connection conn = null;
358 InputStream result = null;
361 String reportName = Tools.getFilenameBase(reportFileName);
362 File reportCompiledFile = ReportResource.getReportCompiledFile(reportName);
364 if (!reportCompiledFile.exists()) {
365 // Need to compile the file.
367 File reportSourceFile = ReportResource.getReportSourceFile(reportName);
369 if(!reportSourceFile.exists()) {
370 logger.error("Report for csid={} is missing source file: {}",
371 reportCSID, reportSourceFile.getAbsolutePath());
373 throw new RuntimeException("Report is missing source file");
376 logger.info("Report for csid={} is not compiled. Compiling first, and saving to: {}",
377 reportCSID, reportCompiledFile.getAbsolutePath());
379 JasperDesign design = JRXmlLoader.load(reportSourceFile.getAbsolutePath());
381 design.setScriptletClass("org.collectionspace.services.report.jasperreports.CSpaceReportScriptlet");
383 JasperCompileManager.compileReportToFile(design, reportCompiledFile.getAbsolutePath());
386 conn = getConnection();
388 if (logger.isTraceEnabled()) {
389 logger.trace("ReportResource for csid=" + reportCSID
390 + " output as " + outputMimeType + " using report file: " + reportCompiledFile.getAbsolutePath());
393 FileInputStream fileStream = new FileInputStream(reportCompiledFile);
395 // export report to pdf and build a response with the bytes
396 //JasperExportManager.exportReportToPdf(jasperprint);
398 JRExporter exporter = null;
399 // Strip extension from report filename.
400 String outputFilename = reportFileName;
401 // Strip extension from report filename.
402 int idx = outputFilename.lastIndexOf(".");
404 outputFilename = outputFilename.substring(0, idx);
405 // Strip any sub-dir from report filename.
406 idx = outputFilename.lastIndexOf(File.separator);
408 outputFilename = outputFilename.substring(idx+1);
409 if(outputMimeType.equals(MediaType.APPLICATION_XML)) {
410 params.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
411 exporter = new JRXmlExporter();
412 outputFilename = outputFilename+".xml";
413 } else if(outputMimeType.equals(MediaType.TEXT_HTML)) {
414 exporter = new JRHtmlExporter();
415 outputFilename = outputFilename+".html";
416 } else if(outputMimeType.equals(ReportClient.PDF_MIME_TYPE)) {
417 exporter = new JRPdfExporter();
418 outputFilename = outputFilename+".pdf";
419 } else if(outputMimeType.equals(ReportClient.CSV_MIME_TYPE)) {
420 params.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
421 exporter = new JRCsvExporter();
422 exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ",");
423 outputFilename = outputFilename+".csv";
424 } else if(outputMimeType.equals(ReportClient.TSV_MIME_TYPE)) {
425 params.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
426 exporter = new JRCsvExporter();
427 exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, "\t");
428 outputFilename = outputFilename+".csv";
429 } else if(outputMimeType.equals(ReportClient.MSWORD_MIME_TYPE) // Understand msword as docx
430 || outputMimeType.equals(ReportClient.OPEN_DOCX_MIME_TYPE)) {
431 exporter = new JRDocxExporter();
432 outputFilename = outputFilename+".docx";
433 } else if(outputMimeType.equals(ReportClient.MSEXCEL_MIME_TYPE) // Understand msexcel as xlsx
434 || outputMimeType.equals(ReportClient.OPEN_XLSX_MIME_TYPE)) {
435 exporter = new JRXlsxExporter();
436 outputFilename = outputFilename+".xlsx";
437 } else if(outputMimeType.equals(ReportClient.MSPPT_MIME_TYPE) // Understand msppt as xlsx
438 || outputMimeType.equals(ReportClient.OPEN_PPTX_MIME_TYPE)) {
439 exporter = new JRPptxExporter();
440 outputFilename = outputFilename+".pptx";
442 logger.error("Reporting: unsupported output MIME type - defaulting to PDF");
443 exporter = new JRPdfExporter();
444 outputFilename = outputFilename+"-default-to.pdf";
446 outReportFileName.append(outputFilename); // Set the out going param to the report's final file name
447 // FIXME: Logging temporarily set to INFO level for CSPACE-5766;
448 // can change to TRACE or DEBUG level as warranted thereafter
449 if (logger.isInfoEnabled()) {
450 logger.info(FileTools.getJavaTmpDirInfo());
453 JasperPrint jasperPrint = JasperFillManager.fillReport(fileStream, params,conn);
455 // Report will be to a temporary file.
456 File tempOutputFile = Files.createTempFile("report-", null).toFile();
457 FileOutputStream tempOutputStream = new FileOutputStream(tempOutputFile);
458 exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
459 exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, tempOutputStream);
460 exporter.exportReport();
461 tempOutputStream.close();
463 result = new FileInputStream(tempOutputFile);
465 } catch (SQLException sqle) {
466 // SQLExceptions can be chained. We have at least one exception, so
467 // set up a loop to make sure we let the user know about all of them
468 // if there happens to be more than one.
469 if (logger.isDebugEnabled()) {
470 SQLException tempException = sqle;
471 while (null != tempException) {
472 logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
474 // loop to the next exception
475 tempException = tempException.getNextException();
478 Response response = Response.status(
479 Response.Status.INTERNAL_SERVER_ERROR).entity(
480 "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
481 throw new CSWebApplicationException(sqle, response);
482 } catch (JRException jre) {
483 if (logger.isDebugEnabled()) {
484 logger.debug("JR Exception: " + jre.getLocalizedMessage() + " Cause: "+jre.getCause());
486 Response response = Response.status(
487 Response.Status.INTERNAL_SERVER_ERROR).entity(
488 "Invoke failed (Jasper problem) on Report csid=" + reportCSID).type("text/plain").build();
489 throw new CSWebApplicationException(jre, response);
490 } catch (FileNotFoundException fnfe) {
491 if (logger.isDebugEnabled()) {
492 logger.debug("FileNotFoundException: " + fnfe.getLocalizedMessage());
494 Response response = Response.status(
495 Response.Status.INTERNAL_SERVER_ERROR).entity(
496 "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
497 throw new CSWebApplicationException(fnfe, response);
502 } catch (SQLException sqle) {
503 // SQLExceptions can be chained. We have at least one exception, so
504 // set up a loop to make sure we let the user know about all of them
505 // if there happens to be more than one.
506 if (logger.isDebugEnabled()) {
507 logger.debug("SQL Exception closing connection: "
508 + sqle.getLocalizedMessage());
510 } catch (Exception e) {
511 if (logger.isDebugEnabled()) {
512 logger.debug("Exception closing connection", e);
519 private Connection getConnection() throws NamingException, SQLException {
520 Connection result = null;
522 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
524 String repositoryName = ctx.getRepositoryName();
525 if (repositoryName != null && repositoryName.trim().isEmpty() == false) {
526 String cspaceInstanceId = ServiceMain.getInstance().getCspaceInstanceId();
527 String databaseName = JDBCTools.getDatabaseName(repositoryName, cspaceInstanceId);
528 result = JDBCTools.getConnection(JDBCTools.NUXEO_READER_DATASOURCE_NAME, databaseName);
530 } catch (Exception e) {
532 throw new NamingException();
539 * Check to see if the current user is authorized to run/invoke this report. If the report
540 * did not specify any permissions, we assume that the current user is authorized to run the report.
541 * @param reportsCommon
544 protected boolean isAuthoritzedWithPermissions(ReportsCommon reportsCommon) {
545 boolean result = true;
547 ResourceActionGroupList resourceActionGroupList = reportsCommon.getResourceActionGroupList();
548 if (resourceActionGroupList != null) {
549 String tenantId = AuthN.get().getCurrentTenantId();
550 for (ResourceActionGroup resourceActionGroup: resourceActionGroupList.getResourceActionGroup()) {
551 String resourceName = resourceActionGroup.getResourceName();
552 ActionGroup actionGroup = ActionGroup.creatActionGroup(resourceActionGroup.getActionGroup());
553 for (ActionType actionType: actionGroup.getActions()) {
554 CSpaceResource res = new URIResourceImpl(tenantId, resourceName, AuthZ.getMethod(actionType));
555 if (AuthZ.get().isAccessAllowed(res) == false) {
566 * Returns true if we found any required permissions.
568 * @param reportCommon
571 private boolean hasRequiredPermissions(ReportsCommon reportCommon) {
572 boolean result = false;
575 result = reportCommon.getResourceActionGroupList().getResourceActionGroup().size() > 0;
576 } catch (NullPointerException e) {
577 // ignore exception, we're just testing to see if we have any list elements
584 * Returns true if we found any required roles.
586 * @param reportCommon
589 private boolean hasRequiredRoles(ReportsCommon reportCommon) {
590 boolean result = false;
593 result = reportCommon.getForRoles().getRoleDisplayName().size() > 0;
594 } catch (NullPointerException e) {
595 // ignore exception, we're just testing to see if we have any list elements
602 * The current user is authorized to run the report if:
603 * 1. No permissions or roles are specified in the report
604 * 2. No roles are specified, but permissions are specified and the current user has those permissions
605 * 3. Roles are specified and the current user is a member of at least one of the roles.
607 * @param reportsCommon
610 protected boolean isAuthoritzed(ReportsCommon reportsCommon) {
611 boolean result = true;
613 if (hasRequiredRoles(reportsCommon)) {
614 result = isAuthorizedWithRoles(reportsCommon);
615 } else if (hasRequiredPermissions(reportsCommon)) {
616 result = isAuthoritzedWithPermissions(reportsCommon);
622 protected boolean isAuthorizedWithRoles(ReportsCommon reportCommon) {
623 boolean result = false;
625 ForRoles forRolesList = reportCommon.getForRoles();
626 if (forRolesList != null) {
627 AccountResource accountResource = new AccountResource();
628 List<String> roleDisplayNameList = accountResource.getAccountRoleDisplayNames(AuthN.get().getUserId(), AuthN.get().getCurrentTenantId());
629 for (String target : forRolesList.getRoleDisplayName()) {
630 if (Tools.listContainsIgnoreCase(roleDisplayNameList, target)) {