[Ils-source] r1564 - in branches/1.6: . src/com/resolutions/ils/data webapp webapp/WEB-INF/classes webapp/WEB-INF/lib

scribe at crosswire.org scribe at crosswire.org
Fri Jan 5 07:57:58 MST 2018


Author: scribe
Date: 2018-01-05 07:57:58 -0700 (Fri, 05 Jan 2018)
New Revision: 1564

Added:
   branches/1.6/webapp/WEB-INF/lib/guava-23.6-jre.jar
   branches/1.6/webapp/WEB-INF/lib/owasp-java-html-sanitizer-20171016.1.jar
Modified:
   branches/1.6/
   branches/1.6/src/com/resolutions/ils/data/CourseAttempt.java
   branches/1.6/src/com/resolutions/ils/data/UserProfile.java
   branches/1.6/webapp/WEB-INF/classes/versions.properties
   branches/1.6/webapp/WEB-INF/lib/ils.jar
   branches/1.6/webapp/admin_profile.jsp
   branches/1.6/webapp/admin_systemmanagement.jsp
   branches/1.6/webapp/aicc.jsp
Log:
merged changes from trunk for 1.81.4 release



Property changes on: branches/1.6
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk:796-1502,1504-1505,1507,1509-1510,1512,1514-1515,1518,1527,1529-1530,1532-1535,1537
   + /trunk:796-1502,1504-1505,1507,1509-1510,1512,1514-1515,1518,1527,1529-1530,1532-1535,1537,1560-1563

Modified: branches/1.6/src/com/resolutions/ils/data/CourseAttempt.java
===================================================================
--- branches/1.6/src/com/resolutions/ils/data/CourseAttempt.java	2018-01-05 14:50:35 UTC (rev 1563)
+++ branches/1.6/src/com/resolutions/ils/data/CourseAttempt.java	2018-01-05 14:57:58 UTC (rev 1564)
@@ -57,9 +57,15 @@
 import java.io.ByteArrayInputStream;
 import org.apache.batik.transcoder.TranscoderOutput;
 
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.List;
+import java.util.ArrayList;
 
 
 
+
+
 public class CourseAttempt extends DataObject {
 
 	public static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); //"EEE MMM dd HH:mm:ss z yyyy");
@@ -761,6 +767,7 @@
 		else if (getCourseAttemptStatusID() == CourseAttempt.STATUS_FAILED) {
 			passedFailed = "FAILED";
 		}
+logger.debug("companyID: " + getCompanyID() + "; apiEnabled: " + apiEnabled + "; callbackURL: " + callbackURL + "; passedFailed: " + passedFailed);
 
 		if (apiEnabled && callbackURL != null) {
 			StringBuffer result = new StringBuffer();
@@ -798,6 +805,9 @@
 				save(orig);
 			}
 		}
+		else {
+			logger.debug("Callback not sent. " + (apiEnabled == false ? "API is not enabled" : "No callback URL is specified."));
+		}
 		logger.debug("end sendStatusUpdateEvent (error:"+error+")");
 		return error;
 	}
@@ -1274,6 +1284,29 @@
 		return data;
 	}
 
+	public static List<String> getINIKeys(String iniBuffer) {
+		List<String> result = new ArrayList<String>();
+		int iniBufferLength = iniBuffer.split("=").length - 1;
+		if (iniBufferLength > 0) {
+			Pattern p = Pattern.compile("([^=|\\\n]*)=");
+			Matcher matcher = p.matcher(iniBuffer);
+			for (int m = 0; m < iniBufferLength; m++) {
+				matcher.find();
+				result.add(matcher.group(1));
+			}
+		}
+		return result;
+	}
+
+	public static String mergeINIValues(String iniBlock, String newData) {
+		List<String> dataKeys = getINIKeys(newData);
+		int dataKeysLength = dataKeys.size();
+		for (int k = 0; k < dataKeysLength; k++) {
+			iniBlock = setINIValue(iniBlock, dataKeys.get(k), getINIValue(newData, dataKeys.get(k)));
+		}
+		return iniBlock;
+	}
+
 	public static String join(String delimeter, Collection items) {
 		if (items == null || items.size() == 0) return "";
 

Modified: branches/1.6/src/com/resolutions/ils/data/UserProfile.java
===================================================================
--- branches/1.6/src/com/resolutions/ils/data/UserProfile.java	2018-01-05 14:50:35 UTC (rev 1563)
+++ branches/1.6/src/com/resolutions/ils/data/UserProfile.java	2018-01-05 14:57:58 UTC (rev 1564)
@@ -30,7 +30,10 @@
 import com.resolutions.ils.Utils;
 import java.util.HashMap;
 import java.io.StringWriter;
+import org.owasp.html.HtmlPolicyBuilder;       
+import org.owasp.html.PolicyFactory; 
 
+
 public class UserProfile extends DataObject {
 	
 	public static final int STATUS_ACTIVE = 1;
@@ -115,6 +118,25 @@
         return new UserProfile();
     }
 
+	static PolicyFactory sanitizer = new HtmlPolicyBuilder()
+		.allowElements("a")
+		.allowUrlProtocols("https")
+		.allowAttributes("href").onElements("a")
+		.requireRelNofollowOnLinks()
+		.toFactory();
+
+	public static String sanitize(String val) {
+		return sanitizer.sanitize(val);
+	}
+
+	// perform sanitation
+	public void setValue(String key, Object val) {
+		if (val instanceof String) {
+			val = sanitize((String)val);
+		}
+		super.setValue(key, val);
+	}
+
     static public int deleteUserProfile(ILSSession session, int userProfileID) {
         UserProfile filter = new UserProfile();
         filter.setCompanyID(session.getCompanyID());

Modified: branches/1.6/webapp/WEB-INF/classes/versions.properties
===================================================================
--- branches/1.6/webapp/WEB-INF/classes/versions.properties	2018-01-05 14:50:35 UTC (rev 1563)
+++ branches/1.6/webapp/WEB-INF/classes/versions.properties	2018-01-05 14:57:58 UTC (rev 1564)
@@ -1 +1 @@
-LMS=V1.81.3
+LMS=V1.81.4

Copied: branches/1.6/webapp/WEB-INF/lib/guava-23.6-jre.jar (from rev 1561, trunk/webapp/WEB-INF/lib/guava-23.6-jre.jar)
===================================================================
(Binary files differ)

Modified: branches/1.6/webapp/WEB-INF/lib/ils.jar
===================================================================
(Binary files differ)

Copied: branches/1.6/webapp/WEB-INF/lib/owasp-java-html-sanitizer-20171016.1.jar (from rev 1561, trunk/webapp/WEB-INF/lib/owasp-java-html-sanitizer-20171016.1.jar)
===================================================================
(Binary files differ)

Modified: branches/1.6/webapp/admin_profile.jsp
===================================================================
--- branches/1.6/webapp/admin_profile.jsp	2018-01-05 14:50:35 UTC (rev 1563)
+++ branches/1.6/webapp/admin_profile.jsp	2018-01-05 14:57:58 UTC (rev 1564)
@@ -132,11 +132,16 @@
           }
         }
         if ((!"dfhdfgfgsf".equals(passwd1) || !"dfhdfgfgsf".equals(passwd2)) && (passwd1 != null)) {
-            if (passwd1.equals(passwd2)) {
+            if (passwd1.equals(UserProfile.sanitize(passwd2))) {
                 current.setUserProfilePasswd(passwd1);
             }
 	    else validError = "Passwords do not match.";
         }
+	// sanitize after we check or else we might match two sanitized passwords and then
+	// the user won't know to what their password has been set
+	passwd1 = UserProfile.sanitize(passwd1);
+	passwd2 = UserProfile.sanitize(passwd2);
+
         val = request.getParameter("statusID");
         if (val != null) current.setUserProfileStatusID(Integer.parseInt(val));
         val = request.getParameter("accessLevel");

Modified: branches/1.6/webapp/admin_systemmanagement.jsp
===================================================================
--- branches/1.6/webapp/admin_systemmanagement.jsp	2018-01-05 14:50:35 UTC (rev 1563)
+++ branches/1.6/webapp/admin_systemmanagement.jsp	2018-01-05 14:57:58 UTC (rev 1564)
@@ -415,6 +415,22 @@
     }
     catch (Exception e) { }	// ok, nothing to upload
 
+
+	if ("testCallback".equals(action)) {
+		logger.debug("Sending test Course Attempt");
+		CourseAttempt ca = new CourseAttempt();
+		ca.setValue("COMPANYID", ilsSession.getCompanyID());
+		ca.defaultAll();
+		ca.setCourseAttemptUserProfileID(user.getUserProfileID());
+		ca.setCourseAttemptCourseID(1);
+		ca.setCourseAttemptStartDate(new Date(System.currentTimeMillis()-60000));
+		ca.setCourseAttemptCompleteDate(new Date());
+		ca.setCourseAttemptStatusID(CourseAttempt.STATUS_FAILED);
+		ca.sendStatusUpdateEvent(pageContext.getServletContext());
+		statusMsg = "A test callback has been sent.";
+		logger.debug("Finished Sending test Course Attempt");
+	}
+
     if ("Save".equals(action)) {
     	boolean saveLog = false;
     	boolean saveSysconfig = false;
@@ -1289,7 +1305,7 @@
 	                            </tr>
 	                            <tr>
 	                              <td class="formHeadings">Callback URL - Course Complete: </td>
-	                              <td colspan="2"><input name="apiCallbackCourseComplete" type="text" value="<%=currentAPICallbackCourseComplete%>" size="40"/>                              </td>
+	                              <td colspan="2"><input id="apiCallbackCourseComplete" name="apiCallbackCourseComplete" type="text" value="<%=currentAPICallbackCourseComplete%>" size="40"/>                              </td>
 	                            </tr>
 	                            <tr>
 	                              <td>&nbsp;</td>
@@ -1297,8 +1313,11 @@
 	                            </tr>
 	                            <tr>
 	                              <td>&nbsp;</td>
-	                              <td colspan="2"><a href="#" onClick="document.getElementById('systemsave').submit()"><img style="border:0;margin:0px 3px 0px 3px;" src="images/save_btn.gif" width="72" height="24" alt=""/></a> <a href="employee.jsp"><img style="border:0;" src="images/cancel_btn.gif" width="72" height="24" alt=""/></a></td>
-	                            </tr>
+	                              <td colspan="2">
+					<a href="#" onClick="document.getElementById('systemsave').submit()"><img style="border:0;margin:0px 3px 0px 3px;" src="images/save_btn.gif" width="72" height="24" alt=""/></a> 
+					<a href="employee.jsp"><img style="border:0;" src="images/cancel_btn.gif" width="72" height="24" alt=""/></a>
+					<a href="#" onClick="$('#testAPICallbackCourseComplete').val($('#apiCallbackCourseComplete').val()); document.getElementById('testCallback').submit(); return false"><img style="border:0;margin:0px 3px 0px 3px;" src="images/run_btn.gif" height="24" alt=""/></a> 
+	                            </td></tr>
 				            </table> </td>
 				          </tr>
 	    </table>
@@ -1552,6 +1571,12 @@
 </div>
 <%@ include file="footer.jsp" %>
 </div>
+<div style="display:none;">
+<form id="testCallback" method="get" action="admin_systemmanagement.jsp">
+<input name="action" value="testCallback" type="hidden"/>
+<input id="testAPICallbackCourseComplete" name="apiCallbackCourseComplete" type="hidden"/>                              </td>
+</form>
+</div>
 
 </body>
 </html>

Modified: branches/1.6/webapp/aicc.jsp
===================================================================
--- branches/1.6/webapp/aicc.jsp	2018-01-05 14:50:35 UTC (rev 1563)
+++ branches/1.6/webapp/aicc.jsp	2018-01-05 14:57:58 UTC (rev 1564)
@@ -6,9 +6,10 @@
 <%@page import="java.util.Vector"%>
 <%@page import="java.util.HashMap"%>
 <%@page import="java.util.Date"%>
+<%@page import="java.util.List"%>
 <%@page import="java.io.File"%>
 <%@page import="java.io.FileWriter"%>
-<%@ page import="org.apache.log4j.Logger" %>
+<%@page import="org.apache.log4j.Logger" %>
 <%!
 
 	void sendNotifications(HttpSession session, CourseAttempt ca, Course course, UserProfile user) {
@@ -44,6 +45,8 @@
 			}
 		}
 	}
+
+	public static final String AICC_INITIAL_DATA = "[core]\r\nlesson_status=i\r\nscore=0\r\nlesson_location=0\r\ntime=00:00:00\r\n";
 %>
 <%
   Logger logger = Logger.getLogger("AICC");
@@ -60,6 +63,8 @@
   String courseID = request.getParameter("courseid");
   String asid = request.getParameter("session_id");
   String aicc_data = request.getParameter("aicc_data");
+  String aicc_userdata = request.getParameter("aicc_userdata");
+  logger.info("aicc_userdata passed: [" + aicc_userdata + "]");
   String preview = request.getParameter("preview");
   CourseAttempt ca = null;
   Course course = null;
@@ -74,6 +79,11 @@
   // Launch a course
   if (courseID != null) {
 	course = Course.getCourse(ilsSession, Integer.parseInt(courseID));
+	if (course == null) {
+		response.setContentType("text/xml");
+		out.print("<error message=\"course ID not found: " + courseID+"\" />");
+		return;
+	}
 
 	if (!"true".equals(preview) || ((user.getUserProfileAccessLevel() < UserProfile.ACCESS_ADMIN) && (!user.hasAccess(UserProfile.ACCESS_MODE_MENU_COURSE_MGMT)))) {
 
@@ -115,7 +125,16 @@
       if ((course.getCourseURL() != null) && (!course.getCourseURL().endsWith("frameset.htm"))) {
 //        ca.setCourseAttemptStatusID(ca.STATUS_PASSED);
       }
+
       ca = ca.saveNew(ilsSession);
+
+	  if (aicc_userdata != null) {
+	  	//If I saveNew with CASTAGE set I get an index out of bounds error
+	  	CourseAttempt orig = (CourseAttempt) ca.clone();
+	  	ca.setCourseAttemptStage(CourseAttempt.mergeINIValues(AICC_INITIAL_DATA, aicc_userdata));
+	  	ca.save(orig);
+	  }
+
 	// what is this crap?!!! Why do we have the same check above separated only by saveNew.
 	// this is only for non-eXpress Course stuff anyway, so I'm not touching it.
       if ((course.getCourseURL() != null) && (!course.getCourseURL().endsWith("frameset.htm"))) {
@@ -123,6 +142,7 @@
       }
     }
     else {
+logger.info("******** relaunching course");
       ca = (CourseAttempt) cas.get(0);
       if (ca.getCourseAttemptStatusID() != ca.STATUS_IN_PROGRESS) {
         CourseAttempt orig = (CourseAttempt) ca.clone();
@@ -140,13 +160,25 @@
           //ca.setCourseAttemptStage("");
         }
 
+
         ca.save(orig);
       }
       else {
         logger.info("Launching in progress course...");
       }
+		// check for aicc_userdata
+		if (aicc_userdata != null) {
+			CourseAttempt orig = (CourseAttempt) ca.clone();
+			String caStage = ca.getCourseAttemptStage();
+logger.info("******** relaunching course: aicc_data existing: " + caStage);
+	  		ca.setCourseAttemptStage(CourseAttempt.mergeINIValues((caStage != null && caStage.length() >= 2) ? caStage : AICC_INITIAL_DATA, aicc_userdata));
+logger.info("******** relaunching course: aicc_data adjusted: " + ca.getCourseAttemptStage());
+			ca.save(orig);
+	  	}
     }
     }
+
+
     String ilsURL = Utils.getSysConfig(session).getProperty("ILSURL");
     String aiccURL = "AICC_URL=" + ((ilsURL == null || ilsURL.length() < 1) ? request.getRequestURL() : (ilsURL+(ilsURL.endsWith("/")?"":"/")+"aicc.jsp"));
     String aiccSID = "AICC_SID=" + (!"true".equals(preview)?ca.getCourseAttemptID():-1);
@@ -158,6 +190,8 @@
 //	response.setHeader("Location", url);
 //	response.setHeader("Connection", "close");
 //	return;
+
+
   }
   else if (asid != null) {
     ca = CourseAttempt.getCourseAttempt(ilsSession, Integer.parseInt(asid));
@@ -175,10 +209,6 @@
     }
 
 
-
-
-
-
 // ---------------------------------------------------------------------
 // CLEARLOG
 // ---------------------------------------------------------------------
@@ -277,11 +307,7 @@
       // code to get [core] node by session_id form value.
       aicc_data = ca.getCourseAttemptStage();
       if ((aicc_data == null) || (aicc_data.length() < 2)) {
-        aicc_data = "[core]\r\n";
-        aicc_data += "lesson_status=i\r\n";
-        aicc_data += "score=0\r\n";
-        aicc_data += "lesson_location=0\r\n";
-        aicc_data += "time=00:00:00\r\n";
+		aicc_data = AICC_INITIAL_DATA;
       }
       else {
         if ("".equals(CourseAttempt.getINIValue(aicc_data, "lesson_location"))) {




More information about the Ils-source mailing list