From e3982f6c2a13c903947a66d89e1af1ccbb161e5f Mon Sep 17 00:00:00 2001 From: "Christopher Lott (cl778h)" Date: Fri, 20 Oct 2017 08:22:19 -0400 Subject: Role management; security vulnerabilities. Extend user/role management interface to allow role deletion. Add filters to defend against common web Javascript attacks. Drop Greensock code with unusable license. Use OParent in EPSDK web application. Issue: US324470, US342324, PORTAL-127 Change-Id: I3a10744fbbbdbda7c88d2b2e542e72e779c9b142 Signed-off-by: Christopher Lott (cl778h) --- .../analytics/controller/ActionHandler.java | 27 +- .../portalsdk/analytics/model/ReportHandler.java | 17 +- .../portalsdk/analytics/model/ReportLoader.java | 22 +- .../portalsdk/analytics/model/SearchHandler.java | 9 +- .../analytics/model/base/ReportWrapper.java | 16 +- .../analytics/model/definition/ReportSchedule.java | 8 +- .../analytics/model/runtime/ReportFormFields.java | 26 +- .../runtime/ReportParamValuesForPDFExcel.java | 22 +- .../analytics/model/runtime/ReportRuntime.java | 4 +- .../onap/portalsdk/analytics/system/AppUtils.java | 4 +- .../fusion/controller/FileServletController.java | 3 +- .../system/fusion/web/RaptorControllerAsync.java | 8 +- ecomp-sdk/epsdk-app-common/pom.xml | 5 + .../controller/core/RoleListController.java | 10 +- .../controller/sample/ElementModelController.java | 13 +- .../onap/portalapp/util/SecurityXssValidator.java | 193 + ecomp-sdk/epsdk-app-os/README.md | 2 +- ecomp-sdk/epsdk-app-os/pom.xml | 130 +- .../onap/portalapp/filter/SecurityXssFilter.java | 130 + .../epsdk-app-os/src/main/webapp/WEB-INF/web.xml | 10 +- .../src/main/resources/ESAPI.properties | 369 ++ .../src/main/resources/validation.properties | 32 + .../external/b2b/js/b2b-angular/b2b-library.min.js | 6926 -------------------- ecomp-sdk/epsdk-core/pom.xml | 6 + .../portalsdk/core/service/ElementLinkService.java | 3 +- .../portalsdk/core/service/ElementMapService.java | 3 +- .../core/service/RoleServiceCentralizedAccess.java | 4 +- .../portalsdk/core/util/SecurityCodecUtil.java | 76 + .../org/onap/portalsdk/core/util/YamlUtils.java | 3 +- .../onap/portalsdk/core/web/support/UserUtils.java | 1 + ecomp-sdk/epsdk-fw/pom.xml | 5 + .../core/onboarding/rest/RestWebServiceClient.java | 4 +- .../portalsdk/core/onboarding/util/CipherUtil.java | 4 +- ecomp-sdk/pom.xml | 15 +- 34 files changed, 969 insertions(+), 7141 deletions(-) create mode 100644 ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java create mode 100644 ecomp-sdk/epsdk-app-os/src/main/java/org/onap/portalapp/filter/SecurityXssFilter.java create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/resources/ESAPI.properties create mode 100644 ecomp-sdk/epsdk-app-overlay/src/main/resources/validation.properties create mode 100644 ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/util/SecurityCodecUtil.java (limited to 'ecomp-sdk') diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/controller/ActionHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/controller/ActionHandler.java index 1ffbde28..36c9d526 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/controller/ActionHandler.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/controller/ActionHandler.java @@ -88,6 +88,7 @@ import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import org.apache.commons.io.FilenameUtils; import org.onap.portalsdk.analytics.error.RaptorException; import org.onap.portalsdk.analytics.error.RaptorRuntimeException; import org.onap.portalsdk.analytics.error.RaptorSchedularException; @@ -127,6 +128,8 @@ import org.onap.portalsdk.analytics.view.ReportData; import org.onap.portalsdk.analytics.xmlobj.DataColumnType; import org.onap.portalsdk.analytics.xmlobj.FormFieldType; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -486,20 +489,13 @@ public class ActionHandler extends org.onap.portalsdk.analytics.RaptorObject { request.getSession().removeAttribute(AppConstants.EMBEDDED_REPORTDATA_MAP); } //String pdfAttachmentKey = AppUtils.getRequestValue(request, "pdfAttachmentKey"); - String report_email_sent_log_id = AppUtils.getRequestValue(request, "log_id"); + String report_email_sent_log_id = ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),AppUtils.getRequestValue(request, "log_id")); logger.debug(EELFLoggerDelegate.debugLogger, ("Email PDF" + pdfAttachmentKey+" "+ report_email_sent_log_id)); //email pdf attachment specific if(nvl(pdfAttachmentKey).length()>0 && report_email_sent_log_id !=null) isEmailAttachment = true; if(isEmailAttachment) { - /* String query = "Select user_id, rep_id from CR_REPORT_EMAIL_SENT_LOG" + - " where rownum = 1" + - " and gen_key='"+pdfAttachmentKey.trim()+"'" + - " and log_id ="+report_email_sent_log_id.trim() + - " and (sysdate - sent_date) < 1 ";*/ - - String query = Globals.getDownloadAllEmailSent(); query = query.replace("[pdfAttachmentKey.trim()]", pdfAttachmentKey.trim()); query = query.replace("[report_email_sent_log_id.trim()]", report_email_sent_log_id.trim()); @@ -1031,7 +1027,8 @@ public class ActionHandler extends org.onap.portalsdk.analytics.RaptorObject { public String getQuickLinksJSON(HttpServletRequest request, String nextPage) { String jsonInString = null; try { - ArrayList quickLinks = ReportLoader.getQuickLinksJSON(request, request.getParameter("quick_links_menu_id"),true); + + ArrayList quickLinks = ReportLoader.getQuickLinksJSON(request, ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),request.getParameter("quick_links_menu_id")),true); ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); @@ -1368,7 +1365,7 @@ public class ActionHandler extends org.onap.portalsdk.analytics.RaptorObject { public String reportDelete(HttpServletRequest request, String nextPage) { try { - String reportID = AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID); + String reportID = ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),AppUtils.getRequestValue(request, AppConstants.RI_REPORT_ID)); try { int i = Integer.parseInt(reportID); } catch(NumberFormatException ex) { @@ -1757,9 +1754,9 @@ public class ActionHandler extends org.onap.portalsdk.analytics.RaptorObject { if(request != null ) { for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff")) - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),request.getParameter(reqParameters[i].toUpperCase()) )); else - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),request.getParameter(reqParameters[i]) )); } } if(session != null ) { @@ -1886,7 +1883,7 @@ public class ActionHandler extends org.onap.portalsdk.analytics.RaptorObject { } } logger.debug(EELFLoggerDelegate.debugLogger, ("SQL2:\n"+ rr.getCachedSQL())); - String fileName = rr.getReportID()+"_"+userId+"_"+timestamp; + String fileName = FilenameUtils.normalize(rr.getReportID()+"_"+userId+"_"+timestamp); boolean flag = false; logger.debug(EELFLoggerDelegate.debugLogger, (""+Utils.isDownloadFileExists(rr.getReportID()+"_"+userId+"_"+dateStr))); // if(Utils.isDownloadFileExists(rr.getReportID()+"_"+userId+"_"+dateStr)) { @@ -1903,8 +1900,8 @@ public class ActionHandler extends org.onap.portalsdk.analytics.RaptorObject { request.setAttribute("message", messageBuffer.toString()); } else if(!flag) { - String whole_fileName = (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_SQL); - String whole_columnsfileName = (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_COLUMNS); + String whole_fileName = FilenameUtils.normalize (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_SQL); + String whole_columnsfileName = FilenameUtils.normalize (Globals.getShellScriptDir() +AppConstants.SHELL_QUERY_DIR+ fileName+AppConstants.FT_COLUMNS); logger.debug(EELFLoggerDelegate.debugLogger, ("FILENAME "+whole_fileName)); diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportHandler.java index 8a5e7e3c..b4c6faac 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportHandler.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportHandler.java @@ -108,6 +108,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.commons.io.FilenameUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDateUtil; @@ -2791,8 +2792,8 @@ public class ReportHandler extends org.onap.portalsdk.analytics.RaptorObject { logger.debug(EELFLoggerDelegate.debugLogger, ("Xls File name " + AppUtils.getTempFolderPath() + xlsFName)); - FileOutputStream xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); + FileOutputStream xlsOut = new FileOutputStream(FilenameUtils.normalize(AppUtils.getTempFolderPath() + + xlsFName)); // BufferedWriter xlsOut = new BufferedWriter(new // FileWriter(AppUtils // .getTempFolderPath() @@ -2904,8 +2905,8 @@ public class ReportHandler extends org.onap.portalsdk.analytics.RaptorObject { for(Iterator iter = setReportRuntime.iterator(); iter.hasNext(); ) { count++; try { - xlsIn = new FileInputStream (AppUtils.getTempFolderPath() - + xlsFName); + xlsIn = new FileInputStream (FilenameUtils.normalize(AppUtils.getTempFolderPath() + + xlsFName)); } catch (FileNotFoundException e) { System.out.println ("File not found in the specified path."); @@ -2914,11 +2915,11 @@ public class ReportHandler extends org.onap.portalsdk.analytics.RaptorObject { if(xlsIn != null) { fileSystem = new POIFSFileSystem (xlsIn); wb = new HSSFWorkbook(fileSystem); - xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); + xlsOut = new FileOutputStream(FilenameUtils.normalize(AppUtils.getTempFolderPath() + + xlsFName)); } else { - xlsOut = new FileOutputStream(AppUtils.getTempFolderPath() - + xlsFName); + xlsOut = new FileOutputStream(FilenameUtils.normalize(AppUtils.getTempFolderPath() + + xlsFName)); wb = new HSSFWorkbook(); } diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportLoader.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportLoader.java index 0d416ae2..3fa3ff91 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportLoader.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/ReportLoader.java @@ -88,6 +88,8 @@ import org.onap.portalsdk.analytics.util.AppConstants; import org.onap.portalsdk.analytics.util.DataSet; import org.onap.portalsdk.analytics.util.Utils; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; public class ReportLoader extends org.onap.portalsdk.analytics.RaptorObject { @@ -488,19 +490,19 @@ public class ReportLoader extends org.onap.portalsdk.analytics.RaptorObject { try{ String sql1= Globals.getDeleteReportRecordLog(); - sql1 = sql1.replace("[reportID]", reportID); + sql1 = sql1.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); String sql2= Globals.getDeleteReportRecordUsers(); - sql2 = sql2.replace("[reportID]", reportID); + sql2 = sql2.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); String sql3= Globals.getDeleteReportRecordSchedule(); - sql3 = sql3.replace("[reportID]", reportID); + sql3 = sql3.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); String sql4= Globals.getDeleteReportRecordAccess(); - sql4 = sql4.replace("[reportID]", reportID); + sql4 = sql4.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); String sql5= Globals.getDeleteReportRecordEmail(); - sql5 = sql5.replace("[reportID]", reportID); + sql5 = sql5.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); String sql6= Globals.getDeleteReportRecordFavorite(); - sql6 = sql6.replace("[reportID]", reportID); + sql6 = sql6.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); String sql7= Globals.getDeleteReportRecordReport(); - sql7 = sql7.replace("[reportID]", reportID); + sql7 = sql7.replace("[reportID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),reportID)); DbUtils.executeUpdate(con, sql1); DbUtils.executeUpdate(con, sql2); @@ -580,9 +582,9 @@ public class ReportLoader extends org.onap.portalsdk.analytics.RaptorObject { roleList.append("," + ((String) iter.next())); String query = Globals.getLoadQuickLinks(); - query = query.replace("[userID]", userID); - query = query.replace("[roleList.toString()]", roleList.toString()); - query = query.replace("[nvls(menuId)]", nvls(menuId)); + query = query.replace("[userID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),userID)); + query = query.replace("[roleList.toString()]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),roleList.toString())); + query = query.replace("[nvls(menuId)]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),nvls(menuId))); DataSet ds = DbUtils .executeQuery(query); diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/SearchHandler.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/SearchHandler.java index 21c260bd..a6043ea7 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/SearchHandler.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/SearchHandler.java @@ -70,6 +70,7 @@ import java.util.Iterator; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.io.FilenameUtils; import org.onap.portalsdk.analytics.controller.ErrorHandler; import org.onap.portalsdk.analytics.error.RaptorException; import org.onap.portalsdk.analytics.model.search.ReportSearchResult; @@ -83,6 +84,8 @@ import org.onap.portalsdk.analytics.system.Globals; import org.onap.portalsdk.analytics.util.AppConstants; import org.onap.portalsdk.analytics.util.DataSet; import org.onap.portalsdk.analytics.util.HtmlStripper; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; public class SearchHandler extends org.onap.portalsdk.analytics.RaptorObject { private static final String HTML_FORM = "forma"; @@ -128,9 +131,9 @@ public class SearchHandler extends org.onap.portalsdk.analytics.RaptorObject { String csvFName = AppUtils.generateFileName(request, (sr.getPageNo() < 0) ? AppConstants.FT_CSV_ALL : AppConstants.FT_CSV); - BufferedWriter csvOut = new BufferedWriter(new FileWriter(AppUtils + BufferedWriter csvOut = new BufferedWriter(new FileWriter(FilenameUtils.normalize(AppUtils .getTempFolderPath() - + csvFName)); + + csvFName))); createCSVFileContent(csvOut, sr); csvOut.close(); @@ -292,7 +295,7 @@ public class SearchHandler extends org.onap.portalsdk.analytics.RaptorObject { } else { rep_name_sql = " AND UPPER(cr.title) LIKE UPPER('%%') "; } - sql = sql.replace("[fReportName]", rep_name_sql); + sql = sql.replace("[fReportName]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),rep_name_sql)); if (menuId.length() > 0){ /*sql += "AND INSTR('|'||cr.menu_id||'|', '|'||'" + menuId + "'||'|') > 0 " diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/base/ReportWrapper.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/base/ReportWrapper.java index 0ba8d4c7..156572f6 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/base/ReportWrapper.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/base/ReportWrapper.java @@ -109,6 +109,8 @@ import org.onap.portalsdk.analytics.xmlobj.Reports; import org.onap.portalsdk.analytics.xmlobj.SemaphoreList; import org.onap.portalsdk.analytics.xmlobj.SemaphoreType; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; /**
* This class is part of RAPTOR (Rapid Application Programming Tool for OLAP Reporting)
@@ -2965,15 +2967,15 @@ public class ReportWrapper extends org.onap.portalsdk.analytics.RaptorObject { for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff")) { if (nvl(request.getParameter(reqParameters[i].toUpperCase())).length() > 0) - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i].toUpperCase()) )); } else - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } for (int i = 0; i < scheduleSessionParameters.length; i++) { if(nvl(request.getParameter(scheduleSessionParameters[i])).trim().length()>0 ) - sql = Utils.replaceInString(sql, "[" + scheduleSessionParameters[i].toUpperCase()+"]", request.getParameter(scheduleSessionParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + scheduleSessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(scheduleSessionParameters[i]) )); } } if(session != null ) { @@ -2998,7 +3000,7 @@ public class ReportWrapper extends org.onap.portalsdk.analytics.RaptorObject { //debugLogger.debug("SQLSQLBASED no formfields " + sql); if(request != null ) { for (int i = 0; i < reqParameters.length; i++) { - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } } if(session != null ) { @@ -3009,9 +3011,9 @@ public class ReportWrapper extends org.onap.portalsdk.analytics.RaptorObject { } } // if it is not multiple select and ParamValue is empty this is the place it can be replaced. - sql = Utils.replaceInString(sql, "[LOGGED_USERID]", userId); - sql = Utils.replaceInString(sql, "[USERID]", userId); - sql = Utils.replaceInString(sql, "[USER_ID]", userId); + sql = Utils.replaceInString(sql, "[LOGGED_USERID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), userId)); + sql = Utils.replaceInString(sql, "[USERID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), userId)); + sql = Utils.replaceInString(sql, "[USER_ID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), userId)); //debugLogger.debug("SQLSQLBASED no formfields after" + sql); //debugLogger.debug("Replacing String 2 "+ sql); //debugLogger.debug("Replaced String " + sql); diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/definition/ReportSchedule.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/definition/ReportSchedule.java index e9a4df1f..f4b54a18 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/definition/ReportSchedule.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/definition/ReportSchedule.java @@ -74,6 +74,8 @@ import org.onap.portalsdk.analytics.util.DataSet; import org.onap.portalsdk.analytics.util.Utils; import org.onap.portalsdk.analytics.xmlobj.FormFieldType; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; public class ReportSchedule extends RaptorObject { @@ -652,9 +654,9 @@ public class ReportSchedule extends RaptorObject { if (paramValue!=null && paramValue.length() > 0) { if(paramValue.toLowerCase().trim().startsWith("select ")) { - paramValue = Utils.replaceInString(paramValue, "[LOGGED_USERID]", userId); - paramValue = Utils.replaceInString(paramValue, "[USERID]", userId); - paramValue = Utils.replaceInString(paramValue, "[USER_ID]", userId); + paramValue = Utils.replaceInString(paramValue, "[LOGGED_USERID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),userId)); + paramValue = Utils.replaceInString(paramValue, "[USERID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),userId)); + paramValue = Utils.replaceInString(paramValue, "[USER_ID]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),userId)); paramValue = Utils.replaceInString(paramValue, "''", "'"); ds = ConnectionUtils.getDataSet(paramValue, dbInfo); diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportFormFields.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportFormFields.java index 0693a1c7..285142f9 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportFormFields.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportFormFields.java @@ -57,6 +57,8 @@ import org.onap.portalsdk.analytics.util.Utils; import org.onap.portalsdk.analytics.xmlobj.ColFilterType; import org.onap.portalsdk.analytics.xmlobj.DataColumnType; import org.onap.portalsdk.analytics.xmlobj.FormFieldType; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; public class ReportFormFields extends Vector { private int nextElemIdx = 0; @@ -96,17 +98,17 @@ public class ReportFormFields extends Vector { if(fieldSQL!=null) { for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff") && (request.getParameter(reqParameters[i].toUpperCase())!=null && request.getParameter(reqParameters[i].toUpperCase()).length() > 0)) - fieldSQL = Utils.replaceInString(fieldSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + fieldSQL = Utils.replaceInString(fieldSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i].toUpperCase()) )); else if (request.getParameter(reqParameters[i])!=null && request.getParameter(reqParameters[i]).length() > 0) - fieldSQL = Utils.replaceInString(fieldSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + fieldSQL = Utils.replaceInString(fieldSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } for (int i = 0; i < scheduleSessionParameters.length; i++) { //s_logger.debug(" Session " + " scheduleSessionParameters[i] " + scheduleSessionParameters[i].toUpperCase() + " " + request.getParameter(scheduleSessionParameters[i])); if(request.getParameter(scheduleSessionParameters[i])!=null && request.getParameter(scheduleSessionParameters[i]).trim().length()>0 ) - fieldSQL = Utils.replaceInString(fieldSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", request.getParameter(scheduleSessionParameters[i]) ); + fieldSQL = Utils.replaceInString(fieldSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(scheduleSessionParameters[i]) )); if(request.getAttribute(scheduleSessionParameters[i])!=null && ((String)request.getAttribute(scheduleSessionParameters[i])).trim().length()>0 ) - fieldSQL = Utils.replaceInString(fieldSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", (String) request.getAttribute(scheduleSessionParameters[i]) ); + fieldSQL = Utils.replaceInString(fieldSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), (String) request.getAttribute(scheduleSessionParameters[i]) )); } @@ -129,16 +131,16 @@ public class ReportFormFields extends Vector { if(fieldDefaultSQL!=null) { for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff") && (request.getParameter(reqParameters[i].toUpperCase())!=null && request.getParameter(reqParameters[i].toUpperCase()).length() > 0)) - fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i].toUpperCase()) )); else if (request.getParameter(reqParameters[i])!=null && request.getParameter(reqParameters[i]).length() > 0) - fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } for (int i = 0; i < scheduleSessionParameters.length; i++) { //s_logger.debug(" Session " + " scheduleSessionParameters[i] " + scheduleSessionParameters[i].toUpperCase() + " " + request.getParameter(scheduleSessionParameters[i])); if(request.getParameter(scheduleSessionParameters[i])!=null && request.getParameter(scheduleSessionParameters[i]).trim().length()>0 ) - fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", request.getParameter(scheduleSessionParameters[i]) ); + fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(scheduleSessionParameters[i]) )); if(request.getAttribute(scheduleSessionParameters[i])!=null && ((String)request.getAttribute(scheduleSessionParameters[i])).trim().length()>0 ) - fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", (String) request.getAttribute(scheduleSessionParameters[i]) ); + fieldDefaultSQL = Utils.replaceInString(fieldDefaultSQL, "[" + scheduleSessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), (String) request.getAttribute(scheduleSessionParameters[i]) )); } @@ -158,9 +160,9 @@ public class ReportFormFields extends Vector { if(rangeStartDateSQL!=null) { for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff") && (request.getParameter(reqParameters[i].toUpperCase())!=null && request.getParameter(reqParameters[i].toUpperCase()).length() > 0)) - rangeStartDateSQL = Utils.replaceInString(rangeStartDateSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + rangeStartDateSQL = Utils.replaceInString(rangeStartDateSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i].toUpperCase()) )); else if (request.getParameter(reqParameters[i])!=null && request.getParameter(reqParameters[i]).length() > 0) - rangeStartDateSQL = Utils.replaceInString(rangeStartDateSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + rangeStartDateSQL = Utils.replaceInString(rangeStartDateSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } for (int i = 0; i < sessionParameters.length; i++) { if (session.getAttribute(sessionParameters[i])!=null && ((String)session.getAttribute(sessionParameters[i])).length() > 0) @@ -170,13 +172,13 @@ public class ReportFormFields extends Vector { if(rangeEndDateSQL!=null) { for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff")&& (request.getParameter(reqParameters[i].toUpperCase())!=null && request.getParameter(reqParameters[i].toUpperCase()).length() > 0)) - rangeEndDateSQL = Utils.replaceInString(rangeEndDateSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + rangeEndDateSQL = Utils.replaceInString(rangeEndDateSQL, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i].toUpperCase()) )); else if (request.getParameter(reqParameters[i])!=null && request.getParameter(reqParameters[i]).length() > 0) rangeEndDateSQL = Utils.replaceInString(rangeEndDateSQL, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); } for (int i = 0; i < sessionParameters.length; i++) { if (session.getAttribute(sessionParameters[i])!=null && ((String)session.getAttribute(sessionParameters[i])).length() > 0) - rangeEndDateSQL = Utils.replaceInString(rangeEndDateSQL, "[" + sessionParameters[i].toUpperCase()+"]", (String)session.getAttribute(sessionParameters[i]) ); + rangeEndDateSQL = Utils.replaceInString(rangeEndDateSQL, "[" + sessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), (String)session.getAttribute(sessionParameters[i]) )); } } String helpText = fft.getComment(); diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportParamValuesForPDFExcel.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportParamValuesForPDFExcel.java index d5911cbb..c50581e4 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportParamValuesForPDFExcel.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportParamValuesForPDFExcel.java @@ -52,6 +52,8 @@ import org.onap.portalsdk.analytics.util.AppConstants; import org.onap.portalsdk.analytics.util.DataSet; import org.onap.portalsdk.analytics.util.Utils; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; public class ReportParamValuesForPDFExcel extends Hashtable { @@ -154,10 +156,10 @@ public class ReportParamValuesForPDFExcel extends Hashtable { if(sql!=null && sql.trim().length()>0){ if(name.equals(ff.getFieldName())){ - sql = Utils.replaceInString(sql, "[VALUE]", value); + sql = Utils.replaceInString(sql, "[VALUE]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),value)); } if(name.equals(ff1.getFieldName())){ - sql = Utils.replaceInString(sql, "["+ff1.getFieldDisplayName()+"]", value); + sql = Utils.replaceInString(sql, "["+ff1.getFieldDisplayName()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),value)); } else continue; } @@ -175,10 +177,10 @@ public class ReportParamValuesForPDFExcel extends Hashtable { if(sql!=null && sql.trim().length()>0){ if(name.equals(ff.getFieldName())){ - sql = Utils.replaceInString(sql, "[VALUE]", value); + sql = Utils.replaceInString(sql, "[VALUE]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),value)); } if(name.equals(ff1.getFieldName())){ - sql = Utils.replaceInString(sql, "["+ff1.getFieldDisplayName()+"]", value); + sql = Utils.replaceInString(sql, "["+ff1.getFieldDisplayName()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),value)); } else continue; } @@ -194,7 +196,7 @@ public class ReportParamValuesForPDFExcel extends Hashtable { if(name.length()<=0) name = ff.getFieldName(); value = rr.getParamValue(name); //debugLogger.debug("Name "+ name+ " value:" + value); - String paramValue = getParamValueForSQL(name, value); + String paramValue = ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), getParamValueForSQL(name, value)); //debugLogger.debug("PDFEXCEL " + name+ " " + ff.getFieldName()+ " " + value + " " + sql +" "+ paramValue); if(name!=null && name.equals(ff.getFieldName())) sql = Utils.replaceInString(sql, "[VALUE]", paramValue); @@ -206,7 +208,7 @@ public class ReportParamValuesForPDFExcel extends Hashtable { FormField ff2 = null; for (Iterator iter1 = rff.iterator(); iter1.hasNext();) { ff2 = (FormField)iter1.next(); - sql = Utils.replaceInString(sql, "[" + ff2.getFieldDisplayName() +"]", getParamValue(ff2.getFieldName())); + sql = Utils.replaceInString(sql, "[" + ff2.getFieldDisplayName() +"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),getParamValue(ff2.getFieldName()))); } //debugLogger.debug("SQL Modified after replacing formfield" + sql); try { @@ -223,21 +225,21 @@ public class ReportParamValuesForPDFExcel extends Hashtable { //debugLogger.debug("B4 request " + sql); if(request != null ) { for (int i = 0; i < scheduleSessionParameters.length; i++) { - sql = Utils.replaceInString(sql, "[" + scheduleSessionParameters[i].toUpperCase()+"]", request.getParameter(scheduleSessionParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + scheduleSessionParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(scheduleSessionParameters[i]) )); } for (int i = 0; i < reqParameters.length; i++) { if(!reqParameters[i].startsWith("ff")) { if (request.getParameter(reqParameters[i])!=null) { sql = Utils.replaceInString(sql, "[" + reqParameters[i]+"]", request.getParameter(reqParameters[i]) ); - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } else { sql = Utils.replaceInString(sql, "[" + reqParameters[i]+"]", request.getParameter(reqParameters[i].toUpperCase()) ); - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i].toUpperCase()) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i].toUpperCase()) )); } } else - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", request.getParameter(reqParameters[i]) ); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase()+"]", ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(reqParameters[i]) )); } } //debugLogger.debug("After request " + sql); diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportRuntime.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportRuntime.java index f9d58fee..03c8214d 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportRuntime.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/model/runtime/ReportRuntime.java @@ -85,6 +85,8 @@ import org.onap.portalsdk.analytics.xmlobj.DataColumnType; import org.onap.portalsdk.analytics.xmlobj.FormFieldType; import org.onap.portalsdk.analytics.xmlobj.ObjectFactory; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; import com.fasterxml.jackson.databind.ObjectMapper; @@ -2455,7 +2457,7 @@ public class ReportRuntime extends ReportWrapper implements Cloneable, Serializa if (param.charAt(startIdx + 1) == '#') { // Parameter is a form field value String fieldId = param.substring(startIdx + 2, endIdx); - String fieldValue = request.getParameter(fieldId); + String fieldValue = ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(fieldId)); sql = Utils.replaceInString(sql, "[" + fieldId.toUpperCase()+"]", fieldValue ); } } diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/AppUtils.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/AppUtils.java index 96bc609f..55735090 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/AppUtils.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/AppUtils.java @@ -47,6 +47,8 @@ import javax.servlet.http.HttpServletRequest; import org.onap.portalsdk.analytics.error.RaptorException; import org.onap.portalsdk.analytics.util.AppConstants; import org.onap.portalsdk.analytics.util.HtmlStripper; +import org.onap.portalsdk.core.util.SecurityCodecUtil; +import org.owasp.esapi.ESAPI; public class AppUtils /* implements IAppUtils */{ private static String baseURL = null; @@ -69,7 +71,7 @@ public class AppUtils /* implements IAppUtils */{ public static String getRequestValue(HttpServletRequest request, String valueID) { String value = (String) request.getAttribute(valueID); if (value == null) - value = request.getParameter(valueID); + value = ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(), request.getParameter(valueID)); return value; } // getRequestValue diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/controller/FileServletController.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/controller/FileServletController.java index 1d1fdd84..b6c985a5 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/controller/FileServletController.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/controller/FileServletController.java @@ -58,6 +58,7 @@ import javax.servlet.http.HttpServletResponse; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.service.DataAccessService; +import org.owasp.esapi.ESAPI; import org.springframework.web.servlet.ModelAndView;; @@ -175,7 +176,7 @@ public class FileServletController { response.setContentLength((int) outStream.length); response.setContentType("application/octet-stream"); response.setHeader("Content-disposition", "attachment; filename=\"" - + name + "\""); + + ESAPI.encoder().canonicalize(name) + "\""); copyStream(response, outStream); } catch (Exception ex) { if (os == null) diff --git a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/web/RaptorControllerAsync.java b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/web/RaptorControllerAsync.java index 8165801c..8478c73c 100644 --- a/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/web/RaptorControllerAsync.java +++ b/ecomp-sdk/epsdk-analytics/src/main/java/org/onap/portalsdk/analytics/system/fusion/web/RaptorControllerAsync.java @@ -105,7 +105,9 @@ import org.onap.portalsdk.analytics.xmlobj.PredefinedValueList; import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.domain.User; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SecurityCodecUtil; import org.onap.portalsdk.core.web.support.UserUtils; +import org.owasp.esapi.ESAPI; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -1415,10 +1417,10 @@ public class RaptorControllerAsync extends RestrictedBaseController { for (int i = 0; i < reqParameters.length; i++) { if (!reqParameters[i].startsWith("ff")) sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase() + "]", - request.getParameter(reqParameters[i].toUpperCase())); + ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),request.getParameter(reqParameters[i].toUpperCase()))); else - sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase() + "]", - request.getParameter(reqParameters[i])); + sql = Utils.replaceInString(sql, "[" + reqParameters[i].toUpperCase() + "]", + ESAPI.encoder().encodeForSQL( SecurityCodecUtil.getCodec(),request.getParameter(reqParameters[i]))); } } if (session != null) { diff --git a/ecomp-sdk/epsdk-app-common/pom.xml b/ecomp-sdk/epsdk-app-common/pom.xml index 089fd092..ebb7c26a 100644 --- a/ecomp-sdk/epsdk-app-common/pom.xml +++ b/ecomp-sdk/epsdk-app-common/pom.xml @@ -232,5 +232,10 @@ spring-webmvc ${springframework.version} + + org.owasp.esapi + esapi + 2.1.0 + diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java index e7682809..b89cb43c 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java @@ -50,6 +50,8 @@ import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.domain.Role; import org.onap.portalsdk.core.domain.User; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; import org.onap.portalsdk.core.service.RoleService; import org.onap.portalsdk.core.web.support.JsonMessage; import org.onap.portalsdk.core.web.support.UserUtils; @@ -73,6 +75,11 @@ public class RoleListController extends RestrictedBaseController { private RoleService service; private String viewName; + + private static final String isAccessCentralized = PortalApiProperties + .getProperty(PortalApiConstants.ROLE_ACCESS_CENTRALIZED); + private static final String isCentralized = "remote"; + @RequestMapping(value = { "/role_list" }, method = RequestMethod.GET) public ModelAndView getRoleList(HttpServletRequest request) { @@ -151,8 +158,9 @@ public class RoleListController extends RestrictedBaseController { Role role = mapper.readValue(root.get("role").toString(), Role.class); Role domainRole = service.getRole(user.getOrgUserId(), role.getId()); - + if (!isCentralized.equals(isAccessCentralized)) { service.deleteDependcyRoleRecord(user.getOrgUserId(), role.getId()); + } service.deleteRole(user.getOrgUserId(), domainRole); logger.info(EELFLoggerDelegate.auditLogger, "Remove role " + domainRole.getId()); diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/ElementModelController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/ElementModelController.java index 34e4db7d..aa327850 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/ElementModelController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/ElementModelController.java @@ -40,6 +40,7 @@ package org.onap.portalapp.controller.sample; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.FilenameUtils; import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.service.ElementLinkService; @@ -57,11 +58,11 @@ public class ElementModelController extends RestrictedBaseController { @RequestMapping(value = { "/elementMapLayout" }, method = RequestMethod.GET, produces = "text/plain") public String layout(HttpServletRequest request, HttpServletResponse response) throws Exception { - String collapseDomains = request.getParameter("collapsedDomains"); - String expandDomains = request.getParameter("expandedDomains"); + String collapseDomains = FilenameUtils.normalize(request.getParameter("collapsedDomains")); + String expandDomains = FilenameUtils.normalize(request.getParameter("expandedDomains")); - String contentFileName = request.getParameter("contentFileName"); - String layoutFileName = request.getParameter("layoutFileName"); + String contentFileName = FilenameUtils.normalize(request.getParameter("contentFileName")); + String layoutFileName = FilenameUtils.normalize(request.getParameter("layoutFileName")); final String realPath = request.getServletContext().getRealPath("/"); logger.debug(EELFLoggerDelegate.debugLogger, "layout: servlet context real path: {}", realPath); @@ -76,8 +77,8 @@ public class ElementModelController extends RestrictedBaseController { @RequestMapping(value = { "/elementMapLink" }, method = RequestMethod.GET, produces = "text/plain") public String callflow(HttpServletRequest request, HttpServletResponse response) throws Exception { - String callFlowName = request.getParameter("callFlowName"); - String callFlowStep = request.getParameter("callFlowStep"); + String callFlowName = FilenameUtils.normalize(request.getParameter("callFlowName")); + String callFlowStep = FilenameUtils.normalize(request.getParameter("callFlowStep")); final String realPath = request.getServletContext().getRealPath("/"); logger.debug(EELFLoggerDelegate.debugLogger, "callflow: servlet context real path: {}", realPath); diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java new file mode 100644 index 00000000..3d2f741c --- /dev/null +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java @@ -0,0 +1,193 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringEscapeUtils; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SystemProperties; +import org.owasp.esapi.ESAPI; +import org.owasp.esapi.codecs.Codec; +import org.owasp.esapi.codecs.MySQLCodec; +import org.owasp.esapi.codecs.OracleCodec; +import org.owasp.esapi.codecs.MySQLCodec.Mode; + +public class SecurityXssValidator { + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SecurityXssValidator.class); + + private static final String MYSQL_DB = "mysql"; + private static final String ORACLE_DB = "oracle"; + private static final String MARIA_DB ="mariadb"; + + + static SecurityXssValidator validator = null; + private static Codec instance; + private static final Lock lock = new ReentrantLock(); + + public static SecurityXssValidator getInstance() { + + if(validator == null) { + lock.lock(); + try { + if(validator == null) + validator = new SecurityXssValidator(); + } finally { + lock.unlock(); + } + } + + return validator; + } + + private SecurityXssValidator() { + // Avoid anything between script tags + XSS_INPUT_PATTERNS.add(Pattern.compile("", Pattern.CASE_INSENSITIVE)); + + // avoid iframes + XSS_INPUT_PATTERNS.add(Pattern.compile("(.*?)", Pattern.CASE_INSENSITIVE)); + + // Avoid anything in a src='...' type of expression + XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)); + + XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)); + + XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*([^>]+)", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)); + + // Remove any lonesome tag + XSS_INPUT_PATTERNS.add(Pattern.compile("", Pattern.CASE_INSENSITIVE)); + + // Remove any lonesome - * - * - * - * - * - * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back". - * @param {!Array.} dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"] - * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition. - * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object) - */ - Definition = function(ns, dependencies, func, global) { - this.sc = (_defLookup[ns]) ? _defLookup[ns].sc : []; //subclasses - _defLookup[ns] = this; - this.gsClass = null; - this.func = func; - var _classes = []; - this.check = function(init) { - var i = dependencies.length, - missing = i, - cur, a, n, cl; - while (--i > -1) { - if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) { - _classes[i] = cur.gsClass; - missing--; - } else if (init) { - cur.sc.push(this); - } - } - if (missing === 0 && func) { - a = ("com.greensock." + ns).split("."); - n = a.pop(); - cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes); - - //exports to multiple environments - if (global) { - _globals[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.) - if (typeof(define) === "function" && define.amd){ //AMD - define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").join("/"), [], function() { return cl; }); - } else if (typeof(module) !== "undefined" && module.exports){ //node - module.exports = cl; - } - } - for (i = 0; i < this.sc.length; i++) { - this.sc[i].check(); - } - } - }; - this.check(true); - }, - - //used to create Definition instances (which basically registers a class that has dependencies). - _gsDefine = window._gsDefine = function(ns, dependencies, func, global) { - return new Definition(ns, dependencies, func, global); - }, - - //a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class). - _class = gs._class = function(ns, func, global) { - func = func || function() {}; - _gsDefine(ns, [], function(){ return func; }, global); - return func; - }; - - _gsDefine.globals = _globals; - - - -/* - * ---------------------------------------------------------------- - * Ease - * ---------------------------------------------------------------- - */ - var _baseParams = [0, 0, 1, 1], - _blankArray = [], - Ease = _class("easing.Ease", function(func, extraParams, type, power) { - this._func = func; - this._type = type || 0; - this._power = power || 0; - this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams; - }, true), - _easeMap = Ease.map = {}, - _easeReg = Ease.register = function(ease, names, types, create) { - var na = names.split(","), - i = na.length, - ta = (types || "easeIn,easeOut,easeInOut").split(","), - e, name, j, type; - while (--i > -1) { - name = na[i]; - e = create ? _class("easing."+name, null, true) : gs.easing[name] || {}; - j = ta.length; - while (--j > -1) { - type = ta[j]; - _easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease(); - } - } - }; - - p = Ease.prototype; - p._calcEnd = false; - p.getRatio = function(p) { - if (this._func) { - this._params[0] = p; - return this._func.apply(null, this._params); - } - var t = this._type, - pw = this._power, - r = (t === 1) ? 1 - p : (t === 2) ? p : (p < 0.5) ? p * 2 : (1 - p) * 2; - if (pw === 1) { - r *= r; - } else if (pw === 2) { - r *= r * r; - } else if (pw === 3) { - r *= r * r * r; - } else if (pw === 4) { - r *= r * r * r * r; - } - return (t === 1) ? 1 - r : (t === 2) ? r : (p < 0.5) ? r / 2 : 1 - (r / 2); - }; - - //create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut) - a = ["Linear","Quad","Cubic","Quart","Quint,Strong"]; - i = a.length; - while (--i > -1) { - p = a[i]+",Power"+i; - _easeReg(new Ease(null,null,1,i), p, "easeOut", true); - _easeReg(new Ease(null,null,2,i), p, "easeIn" + ((i === 0) ? ",easeNone" : "")); - _easeReg(new Ease(null,null,3,i), p, "easeInOut"); - } - _easeMap.linear = gs.easing.Linear.easeIn; - _easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks - - -/* - * ---------------------------------------------------------------- - * EventDispatcher - * ---------------------------------------------------------------- - */ - var EventDispatcher = _class("events.EventDispatcher", function(target) { - this._listeners = {}; - this._eventTarget = target || this; - }); - p = EventDispatcher.prototype; - - p.addEventListener = function(type, callback, scope, useParam, priority) { - priority = priority || 0; - var list = this._listeners[type], - index = 0, - listener, i; - if (list == null) { - this._listeners[type] = list = []; - } - i = list.length; - while (--i > -1) { - listener = list[i]; - if (listener.c === callback && listener.s === scope) { - list.splice(i, 1); - } else if (index === 0 && listener.pr < priority) { - index = i + 1; - } - } - list.splice(index, 0, {c:callback, s:scope, up:useParam, pr:priority}); - if (this === _ticker && !_tickerActive) { - _ticker.wake(); - } - }; - - p.removeEventListener = function(type, callback) { - var list = this._listeners[type], i; - if (list) { - i = list.length; - while (--i > -1) { - if (list[i].c === callback) { - list.splice(i, 1); - return; - } - } - } - }; - - p.dispatchEvent = function(type) { - var list = this._listeners[type], - i, t, listener; - if (list) { - i = list.length; - t = this._eventTarget; - while (--i > -1) { - listener = list[i]; - if (listener.up) { - listener.c.call(listener.s || t, {type:type, target:t}); - } else { - listener.c.call(listener.s || t); - } - } - } - }; - - -/* - * ---------------------------------------------------------------- - * Ticker - * ---------------------------------------------------------------- - */ - var _reqAnimFrame = window.requestAnimationFrame, - _cancelAnimFrame = window.cancelAnimationFrame, - _getTime = Date.now || function() {return new Date().getTime();}, - _lastUpdate = _getTime(); - - //now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill. - a = ["ms","moz","webkit","o"]; - i = a.length; - while (--i > -1 && !_reqAnimFrame) { - _reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; - _cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; - } - - _class("Ticker", function(fps, useRAF) { - var _self = this, - _startTime = _getTime(), - _useRAF = (useRAF !== false && _reqAnimFrame), - _lagThreshold = 500, - _adjustedLag = 33, - _fps, _req, _id, _gap, _nextTime, - _tick = function(manual) { - var elapsed = _getTime() - _lastUpdate, - overlap, dispatch; - if (elapsed > _lagThreshold) { - _startTime += elapsed - _adjustedLag; - } - _lastUpdate += elapsed; - _self.time = (_lastUpdate - _startTime) / 1000; - overlap = _self.time - _nextTime; - if (!_fps || overlap > 0 || manual === true) { - _self.frame++; - _nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap); - dispatch = true; - } - if (manual !== true) { //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise. - _id = _req(_tick); - } - if (dispatch) { - _self.dispatchEvent("tick"); - } - }; - - EventDispatcher.call(_self); - _self.time = _self.frame = 0; - _self.tick = function() { - _tick(true); - }; - - _self.lagSmoothing = function(threshold, adjustedLag) { - _lagThreshold = threshold || (1 / _tinyNum); //zero should be interpreted as basically unlimited - _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); - }; - - _self.sleep = function() { - if (_id == null) { - return; - } - if (!_useRAF || !_cancelAnimFrame) { - clearTimeout(_id); - } else { - _cancelAnimFrame(_id); - } - _req = _emptyFunc; - _id = null; - if (_self === _ticker) { - _tickerActive = false; - } - }; - - _self.wake = function() { - if (_id !== null) { - _self.sleep(); - } else if (_self.frame > 10) { //don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout(). - _lastUpdate = _getTime() - _lagThreshold + 5; - } - _req = (_fps === 0) ? _emptyFunc : (!_useRAF || !_reqAnimFrame) ? function(f) { return setTimeout(f, ((_nextTime - _self.time) * 1000 + 1) | 0); } : _reqAnimFrame; - if (_self === _ticker) { - _tickerActive = true; - } - _tick(2); - }; - - _self.fps = function(value) { - if (!arguments.length) { - return _fps; - } - _fps = value; - _gap = 1 / (_fps || 60); - _nextTime = this.time + _gap; - _self.wake(); - }; - - _self.useRAF = function(value) { - if (!arguments.length) { - return _useRAF; - } - _self.sleep(); - _useRAF = value; - _self.fps(_fps); - }; - _self.fps(fps); - - //a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition. - setTimeout(function() { - if (_useRAF && (!_id || _self.frame < 5)) { - _self.useRAF(false); - } - }, 1500); - }); - - p = gs.Ticker.prototype = new gs.events.EventDispatcher(); - p.constructor = gs.Ticker; - - -/* - * ---------------------------------------------------------------- - * Animation - * ---------------------------------------------------------------- - */ - var Animation = _class("core.Animation", function(duration, vars) { - this.vars = vars = vars || {}; - this._duration = this._totalDuration = duration || 0; - this._delay = Number(vars.delay) || 0; - this._timeScale = 1; - this._active = (vars.immediateRender === true); - this.data = vars.data; - this._reversed = (vars.reversed === true); - - if (!_rootTimeline) { - return; - } - if (!_tickerActive) { //some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly. - _ticker.wake(); - } - - var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline; - tl.add(this, tl._time); - - if (this.vars.paused) { - this.paused(true); - } - }); - - _ticker = Animation.ticker = new gs.Ticker(); - p = Animation.prototype; - p._dirty = p._gc = p._initted = p._paused = false; - p._totalTime = p._time = 0; - p._rawPrevTime = -1; - p._next = p._last = p._onUpdate = p._timeline = p.timeline = null; - p._paused = false; - - - //some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker. - var _checkTimeout = function() { - if (_tickerActive && _getTime() - _lastUpdate > 2000) { - _ticker.wake(); - } - setTimeout(_checkTimeout, 2000); - }; - _checkTimeout(); - - - p.play = function(from, suppressEvents) { - if (from != null) { - this.seek(from, suppressEvents); - } - return this.reversed(false).paused(false); - }; - - p.pause = function(atTime, suppressEvents) { - if (atTime != null) { - this.seek(atTime, suppressEvents); - } - return this.paused(true); - }; - - p.resume = function(from, suppressEvents) { - if (from != null) { - this.seek(from, suppressEvents); - } - return this.paused(false); - }; - - p.seek = function(time, suppressEvents) { - return this.totalTime(Number(time), suppressEvents !== false); - }; - - p.restart = function(includeDelay, suppressEvents) { - return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, (suppressEvents !== false), true); - }; - - p.reverse = function(from, suppressEvents) { - if (from != null) { - this.seek((from || this.totalDuration()), suppressEvents); - } - return this.reversed(true).paused(false); - }; - - p.render = function(time, suppressEvents, force) { - //stub - we override this method in subclasses. - }; - - p.invalidate = function() { - return this; - }; - - p.isActive = function() { - var tl = this._timeline, //the 2 root timelines won't have a _timeline; they're always active. - startTime = this._startTime, - rawTime; - return (!tl || (!this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime()) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale)); - }; - - p._enabled = function (enabled, ignoreTimeline) { - if (!_tickerActive) { - _ticker.wake(); - } - this._gc = !enabled; - this._active = this.isActive(); - if (ignoreTimeline !== true) { - if (enabled && !this.timeline) { - this._timeline.add(this, this._startTime - this._delay); - } else if (!enabled && this.timeline) { - this._timeline._remove(this, true); - } - } - return false; - }; - - - p._kill = function(vars, target) { - return this._enabled(false, false); - }; - - p.kill = function(vars, target) { - this._kill(vars, target); - return this; - }; - - p._uncache = function(includeSelf) { - var tween = includeSelf ? this : this.timeline; - while (tween) { - tween._dirty = true; - tween = tween.timeline; - } - return this; - }; - - p._swapSelfInParams = function(params) { - var i = params.length, - copy = params.concat(); - while (--i > -1) { - if (params[i] === "{self}") { - copy[i] = this; - } - } - return copy; - }; - -//----Animation getters/setters -------------------------------------------------------- - - p.eventCallback = function(type, callback, params, scope) { - if ((type || "").substr(0,2) === "on") { - var v = this.vars; - if (arguments.length === 1) { - return v[type]; - } - if (callback == null) { - delete v[type]; - } else { - v[type] = callback; - v[type + "Params"] = (_isArray(params) && params.join("").indexOf("{self}") !== -1) ? this._swapSelfInParams(params) : params; - v[type + "Scope"] = scope; - } - if (type === "onUpdate") { - this._onUpdate = callback; - } - } - return this; - }; - - p.delay = function(value) { - if (!arguments.length) { - return this._delay; - } - if (this._timeline.smoothChildTiming) { - this.startTime( this._startTime + value - this._delay ); - } - this._delay = value; - return this; - }; - - p.duration = function(value) { - if (!arguments.length) { - this._dirty = false; - return this._duration; - } - this._duration = this._totalDuration = value; - this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration. - if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) { - this.totalTime(this._totalTime * (value / this._duration), true); - } - return this; - }; - - p.totalDuration = function(value) { - this._dirty = false; - return (!arguments.length) ? this._totalDuration : this.duration(value); - }; - - p.time = function(value, suppressEvents) { - if (!arguments.length) { - return this._time; - } - if (this._dirty) { - this.totalDuration(); - } - return this.totalTime((value > this._duration) ? this._duration : value, suppressEvents); - }; - - p.totalTime = function(time, suppressEvents, uncapped) { - if (!_tickerActive) { - _ticker.wake(); - } - if (!arguments.length) { - return this._totalTime; - } - if (this._timeline) { - if (time < 0 && !uncapped) { - time += this.totalDuration(); - } - if (this._timeline.smoothChildTiming) { - if (this._dirty) { - this.totalDuration(); - } - var totalDuration = this._totalDuration, - tl = this._timeline; - if (time > totalDuration && !uncapped) { - time = totalDuration; - } - this._startTime = (this._paused ? this._pauseTime : tl._time) - ((!this._reversed ? time : totalDuration - time) / this._timeScale); - if (!tl._dirty) { //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. - this._uncache(false); - } - //in case any of the ancestor timelines had completed but should now be enabled, we should reset their totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed. - if (tl._timeline) { - while (tl._timeline) { - if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) { - tl.totalTime(tl._totalTime, true); - } - tl = tl._timeline; - } - } - } - if (this._gc) { - this._enabled(true, false); - } - if (this._totalTime !== time || this._duration === 0) { - this.render(time, suppressEvents, false); - if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render. - _lazyRender(); - } - } - } - return this; - }; - - p.progress = p.totalProgress = function(value, suppressEvents) { - return (!arguments.length) ? this._time / this.duration() : this.totalTime(this.duration() * value, suppressEvents); - }; - - p.startTime = function(value) { - if (!arguments.length) { - return this._startTime; - } - if (value !== this._startTime) { - this._startTime = value; - if (this.timeline) if (this.timeline._sortChildren) { - this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct. - } - } - return this; - }; - - p.timeScale = function(value) { - if (!arguments.length) { - return this._timeScale; - } - value = value || _tinyNum; //can't allow zero because it'll throw the math off - if (this._timeline && this._timeline.smoothChildTiming) { - var pauseTime = this._pauseTime, - t = (pauseTime || pauseTime === 0) ? pauseTime : this._timeline.totalTime(); - this._startTime = t - ((t - this._startTime) * this._timeScale / value); - } - this._timeScale = value; - return this._uncache(false); - }; - - p.reversed = function(value) { - if (!arguments.length) { - return this._reversed; - } - if (value != this._reversed) { - this._reversed = value; - this.totalTime(((this._timeline && !this._timeline.smoothChildTiming) ? this.totalDuration() - this._totalTime : this._totalTime), true); - } - return this; - }; - - p.paused = function(value) { - if (!arguments.length) { - return this._paused; - } - if (value != this._paused) if (this._timeline) { - if (!_tickerActive && !value) { - _ticker.wake(); - } - var tl = this._timeline, - raw = tl.rawTime(), - elapsed = raw - this._pauseTime; - if (!value && tl.smoothChildTiming) { - this._startTime += elapsed; - this._uncache(false); - } - this._pauseTime = value ? raw : null; - this._paused = value; - this._active = this.isActive(); - if (!value && elapsed !== 0 && this._initted && this.duration()) { - this.render((tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale), true, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. - } - } - if (this._gc && !value) { - this._enabled(true, false); - } - return this; - }; - - -/* - * ---------------------------------------------------------------- - * SimpleTimeline - * ---------------------------------------------------------------- - */ - var SimpleTimeline = _class("core.SimpleTimeline", function(vars) { - Animation.call(this, 0, vars); - this.autoRemoveChildren = this.smoothChildTiming = true; - }); - - p = SimpleTimeline.prototype = new Animation(); - p.constructor = SimpleTimeline; - p.kill()._gc = false; - p._first = p._last = null; - p._sortChildren = false; - - p.add = p.insert = function(child, position, align, stagger) { - var prevTween, st; - child._startTime = Number(position || 0) + child._delay; - if (child._paused) if (this !== child._timeline) { //we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order). - child._pauseTime = child._startTime + ((this.rawTime() - child._startTime) / child._timeScale); - } - if (child.timeline) { - child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one. - } - child.timeline = child._timeline = this; - if (child._gc) { - child._enabled(true, true); - } - prevTween = this._last; - if (this._sortChildren) { - st = child._startTime; - while (prevTween && prevTween._startTime > st) { - prevTween = prevTween._prev; - } - } - if (prevTween) { - child._next = prevTween._next; - prevTween._next = child; - } else { - child._next = this._first; - this._first = child; - } - if (child._next) { - child._next._prev = child; - } else { - this._last = child; - } - child._prev = prevTween; - if (this._timeline) { - this._uncache(true); - } - return this; - }; - - p._remove = function(tween, skipDisable) { - if (tween.timeline === this) { - if (!skipDisable) { - tween._enabled(false, true); - } - tween.timeline = null; - - if (tween._prev) { - tween._prev._next = tween._next; - } else if (this._first === tween) { - this._first = tween._next; - } - if (tween._next) { - tween._next._prev = tween._prev; - } else if (this._last === tween) { - this._last = tween._prev; - } - - if (this._timeline) { - this._uncache(true); - } - } - return this; - }; - - p.render = function(time, suppressEvents, force) { - var tween = this._first, - next; - this._totalTime = this._time = this._rawPrevTime = time; - while (tween) { - next = tween._next; //record it here because the value could change after rendering... - if (tween._active || (time >= tween._startTime && !tween._paused)) { - if (!tween._reversed) { - tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); - } else { - tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force); - } - } - tween = next; - } - }; - - p.rawTime = function() { - if (!_tickerActive) { - _ticker.wake(); - } - return this._totalTime; - }; - -/* - * ---------------------------------------------------------------- - * TweenLite - * ---------------------------------------------------------------- - */ - var TweenLite = _class("TweenLite", function(target, duration, vars) { - Animation.call(this, duration, vars); - this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method) - - if (target == null) { - throw "Cannot tween a null target."; - } - - this.target = target = (typeof(target) !== "string") ? target : TweenLite.selector(target) || target; - - var isSelector = (target.jquery || (target.length && target !== window && target[0] && (target[0] === window || (target[0].nodeType && target[0].style && !target.nodeType)))), - overwrite = this.vars.overwrite, - i, targ, targets; - - this._overwrite = overwrite = (overwrite == null) ? _overwriteLookup[TweenLite.defaultOverwrite] : (typeof(overwrite) === "number") ? overwrite >> 0 : _overwriteLookup[overwrite]; - - if ((isSelector || target instanceof Array || (target.push && _isArray(target))) && typeof(target[0]) !== "number") { - this._targets = targets = _slice.call(target, 0); - this._propLookup = []; - this._siblings = []; - for (i = 0; i < targets.length; i++) { - targ = targets[i]; - if (!targ) { - targets.splice(i--, 1); - continue; - } else if (typeof(targ) === "string") { - targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings - if (typeof(targ) === "string") { - targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case) - } - continue; - } else if (targ.length && targ !== window && targ[0] && (targ[0] === window || (targ[0].nodeType && targ[0].style && !targ.nodeType))) { //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that