[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> </td>
@@ -1297,8 +1313,11 @@
</tr>
<tr>
<td> </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