From 92b317b2c952c43a29db5a1593c4ae7511a7052b Mon Sep 17 00:00:00 2001 From: Rick Lawson <lawson89@gmail.com> Date: Fri, 26 Sep 2014 08:12:44 -0400 Subject: [PATCH] Clean up javascript in main_new (move ajax functions to goatUtil) Make ajaxify links safe to call multiple times --- .../owasp/webgoat/lessons/AbstractLesson.java | 2 - src/main/webapp/WEB-INF/pages/main_new.jsp | 70 +--------- src/main/webapp/js/goatControllers.js | 6 +- src/main/webapp/js/goatUtil.js | 124 +++++++++++++----- 4 files changed, 98 insertions(+), 104 deletions(-) diff --git a/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java b/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java index 130b81ed5..07e556bb3 100644 --- a/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java +++ b/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java @@ -19,9 +19,7 @@ import org.apache.ecs.Element; import org.apache.ecs.ElementContainer; import org.apache.ecs.StringElement; import org.apache.ecs.html.Body; -import org.apache.ecs.html.Center; import org.apache.ecs.html.Form; -import org.apache.ecs.html.H1; import org.apache.ecs.html.Head; import org.apache.ecs.html.Html; import org.apache.ecs.html.IMG; diff --git a/src/main/webapp/WEB-INF/pages/main_new.jsp b/src/main/webapp/WEB-INF/pages/main_new.jsp index 98e44b6b5..e4216e756 100644 --- a/src/main/webapp/WEB-INF/pages/main_new.jsp +++ b/src/main/webapp/WEB-INF/pages/main_new.jsp @@ -287,80 +287,14 @@ <!--main content end--> </section> + <script> - //Load global functions - - // set this to true if you want to see form submissions - // set to false once we get all the kinks worked out - var DEBUG_FORM_SUBMISSION = false; - $(document).ready(function() { //TODO merge appliction.js code into other js files app.init(); }); - // make all forms ajax forms - var options = { - target: '#lesson_content', // target element(s) to be updated with server response - beforeSubmit: showRequest, // pre-submit callback, comment out after debugging - success: showResponse // post-submit callback, comment out after debugging - - // other available options: - //url: url // override for form's 'action' attribute - //type: type // 'get' or 'post', override for form's 'method' attribute - //dataType: null // 'xml', 'script', or 'json' (expected server response type) - //clearForm: true // clear all form fields after successful submit - //resetForm: true // reset the form after successful submit - - // $.ajax options can be used here too, for example: - //timeout: 3000 - }; - // pre-submit callback - function showRequest(formData, jqForm, options) { - if (DEBUG_FORM_SUBMISSION) { - // formData is an array; here we use $.param to convert it to a string to display it - // but the form plugin does this for you automatically when it submits the data - var queryString = $.param(formData); - - // jqForm is a jQuery object encapsulating the form element. To access the - // DOM element for the form do this: - // var formElement = jqForm[0]; - - alert('About to submit: \n\n' + queryString); - } - - // here we could return false to prevent the form from being submitted; - // returning anything other than false will allow the form submit to continue - return true; - } - - // post-submit callback - function showResponse(responseText, statusText, xhr, $form) { - // for normal html responses, the first argument to the success callback - // is the XMLHttpRequest object's responseText property - - // if the ajaxForm method was passed an Options Object with the dataType - // property set to 'xml' then the first argument to the success callback - // is the XMLHttpRequest object's responseXML property - - // if the ajaxForm method was passed an Options Object with the dataType - // property set to 'json' then the first argument to the success callback - // is the json data object returned by the server - if (DEBUG_FORM_SUBMISSION) { - alert('status: ' + statusText + '\n\nresponseText: \n' + responseText + - '\n\nThe output div should have already been updated with the responseText.'); - } - // JASON - SEE THIS HOOK - // update lesson cookies and params - // make any embedded forms ajaxy - goat.utils.showLessonCookiesAndParams(); - goat.utils.makeFormsAjax(); - // links are hooked with each lesson now (see Java class Screen.getContent()) - //goat.utils.ajaxifyAttackHref(); //TODO find some way to hook scope for current menu. Likely needs larger refactor which is already started/stashed - //refresh menu - angular.element($('#leftside-navigation')).scope().renderMenu(); - } - </script> + <!-- About WebGoat Modal --> <div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg"> diff --git a/src/main/webapp/js/goatControllers.js b/src/main/webapp/js/goatControllers.js index 6a1b47feb..2d3c31d19 100644 --- a/src/main/webapp/js/goatControllers.js +++ b/src/main/webapp/js/goatControllers.js @@ -82,10 +82,10 @@ var goatMenu = function($scope, $http, $modal, $log, $templateCache) { ); //TODO encode html or get angular js portion working $("#lesson_content").html(reply.data); - //hook forms - goat.utils.makeFormsAjax();// inject form? + //hook forms and links (safe to call twice) // links are hooked with each lesson now (see Java class Screen.getContent()) - //goat.utils.ajaxifyAttackHref(); + goat.utils.makeFormsAjax();// inject form? + goat.utils.ajaxifyAttackHref(); $('#leftside-navigation').height($('#main-content').height() + 15)//TODO: get ride of fixed value (15)here //notifies goatLesson Controller of the less change $scope.$emit('lessonUpdate', {params: curScope.parameters, 'showControls': showControls}); diff --git a/src/main/webapp/js/goatUtil.js b/src/main/webapp/js/goatUtil.js index 792314357..2e3e1c897 100644 --- a/src/main/webapp/js/goatUtil.js +++ b/src/main/webapp/js/goatUtil.js @@ -11,16 +11,76 @@ goat.utils = { } return arr; }, + debugFormSubmission: false, + // pre-submit callback + showRequest: function(formData, jqForm, options) { + if (goat.utils.debugFormSubmission) { + // formData is an array; here we use $.param to convert it to a string to display it + // but the form plugin does this for you automatically when it submits the data + var queryString = $.param(formData); + + // jqForm is a jQuery object encapsulating the form element. To access the + // DOM element for the form do this: + // var formElement = jqForm[0]; + + alert('About to submit: \n\n' + queryString); + } + // here we could return false to prevent the form from being submitted; + // returning anything other than false will allow the form submit to continue + return true; + }, + // post-submit callback + showResponse: function(responseText, statusText, xhr, $form) { + // for normal html responses, the first argument to the success callback + // is the XMLHttpRequest object's responseText property + + // if the ajaxForm method was passed an Options Object with the dataType + // property set to 'xml' then the first argument to the success callback + // is the XMLHttpRequest object's responseXML property + + // if the ajaxForm method was passed an Options Object with the dataType + // property set to 'json' then the first argument to the success callback + // is the json data object returned by the server + if (goat.utils.debugFormSubmission) { + alert('status: ' + statusText + '\n\nresponseText: \n' + responseText + + '\n\nThe output div should have already been updated with the responseText.'); + } + // update lesson cookies and params + // make any embedded forms ajaxy + goat.utils.showLessonCookiesAndParams(); + // forms and links are now hooked with each standard lesson render (see Java class Screen.getContent()) + // but these are safe to call twice + goat.utils.makeFormsAjax(); + goat.utils.ajaxifyAttackHref(); //TODO find some way to hook scope for current menu. Likely needs larger refactor which is already started/stashed + //refresh menu + angular.element($('#leftside-navigation')).scope().renderMenu(); + }, makeFormsAjax: function() { + // make all forms ajax forms + var options = { + target: '#lesson_content', // target element(s) to be updated with server response + beforeSubmit: goat.utils.showRequest, // pre-submit callback, comment out after debugging + success: goat.utils.showResponse // post-submit callback, comment out after debugging + + // other available options: + //url: url // override for form's 'action' attribute + //type: type // 'get' or 'post', override for form's 'method' attribute + //dataType: null // 'xml', 'script', or 'json' (expected server response type) + //clearForm: true // clear all form fields after successful submit + //resetForm: true // reset the form after successful submit + + // $.ajax options can be used here too, for example: + //timeout: 3000 + }; //console.log("Hooking any lesson forms to make them ajax"); $("form").ajaxForm(options); }, - displayButton: function(id,show) { - if ($('#'+id)) { + displayButton: function(id, show) { + if ($('#' + id)) { if (show) { - $('#'+id).show(); + $('#' + id).show(); } else { - $('#'+id).hide(); + $('#' + id).hide(); } } }, @@ -52,17 +112,17 @@ goat.utils = { $('#lesson_plan_row').show(); goat.utils.scrollToHelp(); }, - scrollToHelp:function() { - $('#leftside-navigation').height($('#main-content').height()+15) + scrollToHelp: function() { + $('#leftside-navigation').height($('#main-content').height() + 15) var target = $('#lessonHelpsWrapper'); goat.utils.scrollEasy(target); }, scrollToTop: function() { $('.lessonHelp').hide(); - var target= $('#container'); + var target = $('#container'); goat.utils.scrollEasy(target); }, - scrollEasy:function(target) { + scrollEasy: function(target) { $('html,body').animate({ scrollTop: target.offset().top }, 1000); @@ -73,7 +133,7 @@ goat.utils = { } var params = url.split('?')[1].split('&'); var paramsArr = []; - for (var i=0;i< params.length;i++) { + for (var i = 0; i < params.length; i++) { var paramObj = {}; paramObj.name = params[i].split('=')[0]; paramObj.value = params[i].split('=')[1]; @@ -84,33 +144,35 @@ goat.utils = { highlightCurrentLessonMenu: function(id) { //TODO: move selectors in first two lines into goatConstants $('ul li.selected').removeClass(goatConstants.selectedMenuClass) - $('ul li.selected a.selected').removeClass(goatConstants.selectedMenuClass) - $('#'+id).addClass(goatConstants.selectedMenuClass); - $('#'+id).parent().addClass(goatConstants.selectedMenuClass); + $('ul li.selected a.selected').removeClass(goatConstants.selectedMenuClass) + $('#' + id).addClass(goatConstants.selectedMenuClass); + $('#' + id).parent().addClass(goatConstants.selectedMenuClass); }, - makeId: function (lessonName) { - return lessonName.replace(/\s|\(|\)|\!|\:|\;|\@|\#|\$|\%|\^|\&|\*/g,'');//TODO move the replace routine into util function + makeId: function(lessonName) { + return lessonName.replace(/\s|\(|\)|\!|\:|\;|\@|\#|\$|\%|\^|\&|\*/g, '');//TODO move the replace routine into util function }, - ajaxifyAttackHref: function () { + ajaxifyAttackHref: function() { /* Jason I commented this implementation out * I think we should show the attack link on the lessons that need it by modifying the lesson * itself or we could add a new button up top for "show lesson link" - $.each($('a[href^="attack?"]'), - function(i,el) { - var url = $(el).attr('href'); - $(el).attr('href','#'); - $(el).attr('link',url); - //TODO pull currentMenuId - $(el).click( - function() { - var _url = $(el).attr('link'); - $.get(_url, {success:showResponse}); - } - ) - } - ); - */ - // alternate implementation + $.each($('a[href^="attack?"]'), + function(i,el) { + var url = $(el).attr('href'); + $(el).attr('href','#'); + $(el).attr('link',url); + //TODO pull currentMenuId + $(el).click( + function() { + var _url = $(el).attr('link'); + $.get(_url, {success:showResponse}); + } + ) + } + ); + */ + // alternate implementation + // unbind any bound events so we are safe to be called twice + $('#lesson_content a').unbind('click'); $('#lesson_content a').bind('click', function(event) { event.preventDefault(); $.get(this.href, {}, function(response) {