From e9cd630a95cf4b9373e0ad6095567cdf103596d7 Mon Sep 17 00:00:00 2001
From: "lawson89@gmail.com" <>
Date: Sun, 7 Sep 2014 23:39:05 -0400
Subject: [PATCH] get the info button functioning

---
 .../org/owasp/webgoat/controller/About.java   |  49 ++++
 src/main/webapp/WEB-INF/pages/about.jsp       | 124 ++++++++
 src/main/webapp/WEB-INF/pages/main_new.jsp    | 215 +++++++-------
 src/main/webapp/js/goatControllers.js         | 266 +++++++++---------
 4 files changed, 420 insertions(+), 234 deletions(-)
 create mode 100644 src/main/java/org/owasp/webgoat/controller/About.java
 create mode 100644 src/main/webapp/WEB-INF/pages/about.jsp

diff --git a/src/main/java/org/owasp/webgoat/controller/About.java b/src/main/java/org/owasp/webgoat/controller/About.java
new file mode 100644
index 000000000..479f83a74
--- /dev/null
+++ b/src/main/java/org/owasp/webgoat/controller/About.java
@@ -0,0 +1,49 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.owasp.webgoat.controller;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+/**
+ *
+ * @author rlawson
+ */
+@Controller
+public class About {
+    
+    final Logger logger = LoggerFactory.getLogger(About.class);
+    private static final String WELCOMED = "welcomed";
+    
+    @RequestMapping(value = "about.mvc", method = RequestMethod.GET)
+    public ModelAndView welcome(HttpServletRequest request,
+            @RequestParam(value = "error", required = false) String error,
+            @RequestParam(value = "logout", required = false) String logout) {
+
+        // set the welcome attribute
+        // this is so the attack servlet does not also 
+        // send them to the welcome page
+        HttpSession session = request.getSession();
+        if (session.getAttribute(WELCOMED) == null) {
+            session.setAttribute(WELCOMED, "true");
+        }
+        
+        //go ahead and send them to webgoat (skip the welcome page)
+        ModelAndView model = new ModelAndView();
+        //model.setViewName("welcome");
+        //model.setViewName("main_new");
+        model.setViewName("about");
+        return model;
+    }
+    
+}
diff --git a/src/main/webapp/WEB-INF/pages/about.jsp b/src/main/webapp/WEB-INF/pages/about.jsp
new file mode 100644
index 000000000..785761353
--- /dev/null
+++ b/src/main/webapp/WEB-INF/pages/about.jsp
@@ -0,0 +1,124 @@
+<%@ page contentType="text/html; charset=ISO-8859-1" language="java"
+         errorPage=""%>
+
+<!-- Latest compiled and minified CSS -->
+<link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css"/>
+<link rel="stylesheet" href="css/webgoat.css" type="text/css" />
+
+<div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
+    <h1 class="modal-title" id="myModalLabel">About WebGoat</h1>
+</div>
+<div class="modal-body">
+    <p>Thank you for using WebGoat! This program is a demonstration of common web application flaws.
+        The exercises are intended to provide hands on experience with
+        application penetration testing techniques. </p>
+    <p>The WebGoat project is led
+        by Bruce Mayhew. Please send all comments to Bruce at [TODO, session was blowing up here for some reason].</p>
+
+    <div id="team">
+        <table border="0" align="center" class="lessonText">
+            <tr>
+                <td width="50%">
+                    <div align="center"><a href="http://www.owasp.org"><img
+                                border="0" src="images/logos/owasp.jpg" alt="OWASP Foundation"
+                                longdesc="http://www.owasp.org" /></a></div>
+                </td>
+                <td width="50%">
+                    <div align="center"><a href="http://www.aspectsecurity.com"><img
+                                border="0" src="images/logos/aspect.jpg" alt="Aspect Security"
+                                longdesc="http://www.aspectsecurity.com" /></a></div>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <div align="center"><span class="style1">
+                            WebGoat Authors </span></div>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <div align="center"><span class="style2">
+                            Bruce Mayhew </span></div>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <div align="center"><span class="style2">
+                            Jeff Williams </span></div>
+                </td>
+            </tr>
+            <tr>
+                <td width="50%">
+                    <div align="center"><span class="style1"><br />
+                            WebGoat Design Team </span></div>
+                </td>
+                <td width="50%">
+                    <div align="center"><span class="style1"><br />
+                            V5.4 Lesson Contributers </span></div>
+                </td>
+            </tr>
+            <tr>
+                <td valign="top">
+                    <div align="center" class="style2">David Anderson</div>
+                    <div align="center" class="style2">Laurence Casey (Graphics)</div>
+                    <div align="center" class="style2">Rogan Dawes</div>
+                    <div align="center" class="style2">Bruce Mayhew</div>
+                </td>
+                <td valign="top">
+                    <div align="center" class="style2">Sherif Koussa</div>
+                    <div align="center" class="style2">Yiannis Pavlosoglou</div>
+                    <div align="center" class="style2"></div>
+
+                </td>
+            </tr>
+            <tr>
+                <td height="25" valign="bottom">
+                    <div align="center"><span class="style1">Special Thanks
+                            for V5.4</span></div>
+                </td>
+                <td height="25" valign="bottom">
+                    <div align="center"><span class="style1">Documentation
+                            Contributers</span></div>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    <div align="center" class="style2">Brian Ciomei (Multitude of bug fixes)</div>
+                    <div align="center" class="style2">To all who have sent comments</div>
+
+                </td>
+                <td>
+                    <div align="center" class="style2">
+                        <a href="http://www.zionsecurity.com/" target="_blank">Erwin Geirnaert</a></div>
+                    <div align="center" class="style2">
+                        <a href="http://yehg.org/" target="_blank">Aung Khant</a></div>
+                    <div align="center" class="style2">
+                        <a href="http://www.softwaresecured.com" target="blank">Sherif Koussa</a>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    <div align="center" class="style2">&nbsp;</div>
+                </td>
+            </tr>
+        </table>
+    </div>
+    <div align="center" class="style2">&nbsp;</div>
+    <div align="center" class="style2">&nbsp;</div>
+    <div align="center" class="style2">&nbsp;</div>
+    <div id="warning">WARNING<br />
+        While running this program, your machine is extremely vulnerable to
+        attack if you are not running on localhost. If you are NOT running on localhost (default configuration), You should disconnect from the network while using this program.
+        <br />
+        <br />
+        This program is for educational purposes only. Use of these techniques
+        without permission could lead to job termination, financial liability,
+        and/or criminal penalties.</div>
+</div>
+<div class="modal-footer">
+    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+</div>
+
+
diff --git a/src/main/webapp/WEB-INF/pages/main_new.jsp b/src/main/webapp/WEB-INF/pages/main_new.jsp
index 9dce8ee1d..602a00a94 100644
--- a/src/main/webapp/WEB-INF/pages/main_new.jsp
+++ b/src/main/webapp/WEB-INF/pages/main_new.jsp
@@ -76,7 +76,7 @@
                     <h1 id="lessonTitle">Lesson Title in here</h1>
                 </div><!--lesson title end-->
                 <div class="user-nav pull-right">
-                    <button type="button" class="btn btn-default">
+                    <button type="button" class="btn btn-default" ng-click="showAbout()">
                         <i class="fa fa-info"></i>
                     </button>
                     <button type="button" class="btn btn-default">
@@ -120,11 +120,11 @@
                                     <div class="panel-body">
                                         <button type="button" id="showSourceBtn" class="btn btn-primary btn-xs" ng-click="showLessonSource()">Java [Source]</button>
                                         <button type="button" id="showSolutionBtn" class="btn btn-primary btn-xs" ng-click="showLessonSolution()">Solution</button>
-					<button type="button" id="showPlanBtn" class="btn btn-primary btn-xs" ng-click="showLessonPlan()">Lesson Plan</button>
-					<button type="button" id="showHintsBtn" class="btn btn-primary btn-xs"  ng-click="viewHints()">Hints</button>
+                                        <button type="button" id="showPlanBtn" class="btn btn-primary btn-xs" ng-click="showLessonPlan()">Lesson Plan</button>
+                                        <button type="button" id="showHintsBtn" class="btn btn-primary btn-xs"  ng-click="viewHints()">Hints</button>
                                     </div>
                                 </div>
-				
+
                             </div>
                             <div class="col-md-12">
                                 <div class="panel" >
@@ -140,57 +140,57 @@
                                 <div class="panel">
                                     <div class="panel-body">
                                         <div align="left">
-					    <h3>Cookies / Parameters</h3>
+                                            <h3>Cookies / Parameters</h3>
                                         </div>
                                         <hr />
-					<div id="cookiesAndParamsView">
-					    <div class="cookiesView">
-						<h4>Cookies</h4>
-					    <table class="cookieTable table-striped table-nonfluid" ng-repeat="cookie in cookies">
-						<thead>
-						    <tr><th>Field</th><th>Value</th></tr>
-						</thead>
-						<tbody>
-						    <tr ng-repeat="(key, value) in cookie">
-							<td>{{key}}</td>
-							<td>{{value}}</td>
-						    </tr>
-						</tbody>
-					        <!--<li ng-repeat="(key, value) in cookie">{{key}} :: {{ value}} </td>-->
-					    <!--</ul>-->
-					    </table>
-					</div>
-				        <div id="paramsView"> <!--class="paramsView"-->
-					<h4>Params</h4>
-                                        <table class="paramsTable table-striped table-nonfluid" id="paramsTable">
-					    <thead>
-						<tr><th>Param</th><th>Value</th></tr>
-					    </thead>
-					    <tbody>
-						<tr ng-repeat="param in parameters">
-						    <td>{{param.name}}</td>
-						    <td>{{param.value}}</td>
-						</tr>						
-					    </tbody>
-					</table>
-                                        </ul>
-					</div>
-				    </div>
+                                        <div id="cookiesAndParamsView">
+                                            <div class="cookiesView">
+                                                <h4>Cookies</h4>
+                                                <table class="cookieTable table-striped table-nonfluid" ng-repeat="cookie in cookies">
+                                                    <thead>
+                                                        <tr><th>Field</th><th>Value</th></tr>
+                                                    </thead>
+                                                    <tbody>
+                                                        <tr ng-repeat="(key, value) in cookie">
+                                                            <td>{{key}}</td>
+                                                            <td>{{value}}</td>
+                                                        </tr>
+                                                    </tbody>
+                                                    <!--<li ng-repeat="(key, value) in cookie">{{key}} :: {{ value}} </td>-->
+                                                    <!--</ul>-->
+                                                </table>
+                                            </div>
+                                            <div id="paramsView"> <!--class="paramsView"-->
+                                                <h4>Params</h4>
+                                                <table class="paramsTable table-striped table-nonfluid" id="paramsTable">
+                                                    <thead>
+                                                        <tr><th>Param</th><th>Value</th></tr>
+                                                    </thead>
+                                                    <tbody>
+                                                        <tr ng-repeat="param in parameters">
+                                                            <td>{{param.name}}</td>
+                                                            <td>{{param.value}}</td>
+                                                        </tr>						
+                                                    </tbody>
+                                                </table>
+                                                </ul>
+                                            </div>
+                                        </div>
                                     </div>
                                 </div>
                             </div>
                         </div><!--col-md-4 end-->         
                     </div>
                     <div id="lessonHelpsWrapper">
-			<div class="row lessonHelp" id="lesson_hint_row">
+                        <div class="row lessonHelp" id="lesson_hint_row">
                             <div class="col-md-12">
                                 <h4>Hints</h4>
                                 <div class="panel" >
                                     <div class="panel-body" id="lesson_hint">
-					<span class="glyphicon-class glyphicon glyphicon-circle-arrow-left" id="showPrevHintBtn" ng-click="viewPrevHint()"></span>
-					<span class="glyphicon-class glyphicon glyphicon-circle-arrow-right" id="showNextHintBtn" ng-click="viewNextHint()"></span>
-					<br/>
-					{{curHint}}
+                                        <span class="glyphicon-class glyphicon glyphicon-circle-arrow-left" id="showPrevHintBtn" ng-click="viewPrevHint()"></span>
+                                        <span class="glyphicon-class glyphicon glyphicon-circle-arrow-right" id="showNextHintBtn" ng-click="viewNextHint()"></span>
+                                        <br/>
+                                        {{curHint}}
                                     </div>                                    
                                 </div>
                             </div>
@@ -220,7 +220,7 @@
                                 <h4>Lesson Plan</h4>
                                 <div class="panel" >
                                     <div class="panel-body" id="lesson_plan">
-					<!-- allowing jQuery to handle this one -->
+                                        <!-- allowing jQuery to handle this one -->
                                     </div>                                    
                                 </div>
                             </div>
@@ -239,7 +239,7 @@
                                 <h4>Lesson Source Code</h4>
                                 <div class="panel">
                                     <div class="panel-body" id="lesson_source">
-					<pre>{{source}}</pre>
+                                        <pre>{{source}}</pre>
                                     </div>                                    
                                 </div>
                             </div>
@@ -255,76 +255,83 @@
         <!-- TODO pull source into project instead of loading from external -->
         <script src="http://malsup.github.com/jquery.form.js"></script>  
         <script>
-                                                    //Load global functions
+                                            //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;
+                                            // 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() {
-                                                        app.init();
-							//can be augmented later to 'resume' for a given user ... currently kluged to start at fixed lesson
-							var url = 'attack?Screen=32&menu=5';
-							angular.element($('#leftside-navigation')).scope().renderLesson(url);
-                                                    });
-                                                    // 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 
+                                            $(document).ready(function() {
+                                                app.init();
+                                                //can be augmented later to 'resume' for a given user ... currently kluged to start at fixed lesson
+                                                var url = 'attack?Screen=32&menu=5';
+                                                angular.element($('#leftside-navigation')).scope().renderLesson(url);
+                                            });
+                                            // 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 
+                                                        // 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);
+                                                        // $.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]; 
+                                                    // 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);
-                                                        }
+                                                    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;
-                                                    }
+                                                // 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 
+                                            // 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 '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();
-                                                    }
+                                                // 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();
+                                            }
 
         </script>
+        <!-- Modal -->
+        <div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+            <div class="modal-dialog modal-lg">
+                <div class="modal-content">
+                </div>
+            </div>
+        </div>
     </body>
 </html>
diff --git a/src/main/webapp/js/goatControllers.js b/src/main/webapp/js/goatControllers.js
index e29d16e09..88aa79379 100644
--- a/src/main/webapp/js/goatControllers.js
+++ b/src/main/webapp/js/goatControllers.js
@@ -7,162 +7,168 @@
  *  prepares and updates menu topic items for the view
  */
 goat.controller('goatLesson', function($scope, $http, $modal, $log, $templateCache) {
-    $scope.cookies= [];
-    $scope.params=[];
+    $scope.cookies = [];
+    $scope.params = [];
     //TODO: implement via separate promise and use config for menu (goat.data.loadMenuData())
     $http({method: 'GET', url: goatConstants.lessonService}).then(
-	function(menuData) {
-	    var menuItems = goat.utils.addMenuClasses(goatConstants.menuPrefix.concat(menuData.data));
-	    $scope.menuTopics = menuItems;
-	},
-	function(error) {
-	    // TODO - handle this some way other than an alert
-	    console.error("Error rendering menu: " + error);
-	}    
+            function(menuData) {
+                var menuItems = goat.utils.addMenuClasses(goatConstants.menuPrefix.concat(menuData.data));
+                $scope.menuTopics = menuItems;
+            },
+            function(error) {
+                // TODO - handle this some way other than an alert
+                console.error("Error rendering menu: " + error);
+            }
     );
-    
+
     $scope.renderLesson = function(url) {
         //console.log(url + ' was passed in');
         // use jquery to render lesson content to div
-	$scope.hintIndex = 0;
-	
-	var curScope = $scope;
-	
-	
-	curScope.parameters = goat.utils.scrapeParams(url);
+        $scope.hintIndex = 0;
+
+        var curScope = $scope;
+
+
+        curScope.parameters = goat.utils.scrapeParams(url);
         goat.data.loadLessonContent(url).then(
-		function(reply) {
-		    $("#lesson_content").html(reply);
-		    //hook forms
-		    goat.utils.makeFormsAjax();
-		    $('#hintsView').hide();
-		    //render lesson title
-		    $('#lessonTitle').text(goat.utils.extractLessonTitle($(reply)));
-		    //@KLUGE to remove h1 after extracting and moving it to top
-		    $('#lesson_content h1').remove()
-		    // adjust menu to lessonContent size if necssary
-		    //@TODO: this is still clunky ... needs some TLC
-		    if ($('div.panel-body').height() > 400) {
-			$('#leftside-navigation').height($(window).height());
-		    }
-		    //cookies
-		    goat.data.loadCookies().then(
-			function(resp) {
-			    curScope.cookies = resp;
-			}
-		    );
-		    //hints
-		    curScope.hintIndex=0;
-		    goat.data.loadHints().then(
-			function (resp) {
-			    curScope.hints = resp;
-			    if (curScope.hints.length > 0 && curScope.hints[0].hint.indexOf(goatConstants.noHints) === -1) {
-				goat.utils.displayButton('showHintsBtn',true);
-                            } else {
-                                goat.utils.displayButton('showHintsBtn',false);
+                function(reply) {
+                    $("#lesson_content").html(reply);
+                    //hook forms
+                    goat.utils.makeFormsAjax();
+                    $('#hintsView').hide();
+                    //render lesson title
+                    $('#lessonTitle').text(goat.utils.extractLessonTitle($(reply)));
+                    //@KLUGE to remove h1 after extracting and moving it to top
+                    $('#lesson_content h1').remove()
+                    // adjust menu to lessonContent size if necssary
+                    //@TODO: this is still clunky ... needs some TLC
+                    if ($('div.panel-body').height() > 400) {
+                        $('#leftside-navigation').height($(window).height());
+                    }
+                    //cookies
+                    goat.data.loadCookies().then(
+                            function(resp) {
+                                curScope.cookies = resp;
                             }
-			}
-		    );
-		    //source
-		    goat.data.loadSource().then(
-			function(resp) {
-			    curScope.source = resp;
-			}
-		    );
-		    //plan
-		    goat.data.loadPlan().then(
-			function(resp) {
-			    curScope.plan = resp;
-			}
-		    );
-		    //solution
-		    goat.data.loadSolution().then(
-			function(resp) {
-			    curScope.solution = resp;
-			}
-		    );
-		    goat.utils.scrollToTop();
-		}
-	    );
+                    );
+                    //hints
+                    curScope.hintIndex = 0;
+                    goat.data.loadHints().then(
+                            function(resp) {
+                                curScope.hints = resp;
+                                if (curScope.hints.length > 0 && curScope.hints[0].hint.indexOf(goatConstants.noHints) === -1) {
+                                    goat.utils.displayButton('showHintsBtn', true);
+                                } else {
+                                    goat.utils.displayButton('showHintsBtn', false);
+                                }
+                            }
+                    );
+                    //source
+                    goat.data.loadSource().then(
+                            function(resp) {
+                                curScope.source = resp;
+                            }
+                    );
+                    //plan
+                    goat.data.loadPlan().then(
+                            function(resp) {
+                                curScope.plan = resp;
+                            }
+                    );
+                    //solution
+                    goat.data.loadSolution().then(
+                            function(resp) {
+                                curScope.solution = resp;
+                            }
+                    );
+                    goat.utils.scrollToTop();
+                }
+        );
     };
-    
-    $scope.showLessonSource = function () {
-	$('.lessonHelp').hide();
+
+    $scope.showLessonSource = function() {
+        $('.lessonHelp').hide();
         $('#lesson_source_row').show();
         goat.utils.scrollToHelp();
     }
-    
-    $scope.showLessonPlan = function () {
-	$('.lessonHelp').hide();
-	$("#lesson_plan").html($scope.plan);
+
+    $scope.showLessonPlan = function() {
+        $('.lessonHelp').hide();
+        $("#lesson_plan").html($scope.plan);
         $('#lesson_plan_row').show();
         goat.utils.scrollToHelp();
     }
 
-    $scope.showLessonSolution = function () {
-	$('.lessonHelp').hide();
-	$("#lesson_solution").html($scope.solution);
+    $scope.showLessonSolution = function() {
+        $('.lessonHelp').hide();
+        $("#lesson_solution").html($scope.solution);
         $('#lesson_solution_row').show();
         goat.utils.scrollToHelp();
     }
 
-    $scope.manageHintButtons = function () {
-	if ($scope.hintIndex === $scope.hints.length -1) {
-	    $('#showNextHintBtn').css('visibility','hidden');
-	} else if ($scope.hintIndex < $scope.hints.length - 1) {
-	    $('#showNextHintBtn').css('visibility','visible');
-	}
-	//
-	if ($scope.hintIndex === 0) {
-	    $('#showPrevHintBtn').css('visibility','hidden');
-	} else if ($scope.hintIndex > 0) {
-	    $('#showPrevHintBtn').css('visibility','visible');
-	}
+    $scope.manageHintButtons = function() {
+        if ($scope.hintIndex === $scope.hints.length - 1) {
+            $('#showNextHintBtn').css('visibility', 'hidden');
+        } else if ($scope.hintIndex < $scope.hints.length - 1) {
+            $('#showNextHintBtn').css('visibility', 'visible');
+        }
+        //
+        if ($scope.hintIndex === 0) {
+            $('#showPrevHintBtn').css('visibility', 'hidden');
+        } else if ($scope.hintIndex > 0) {
+            $('#showPrevHintBtn').css('visibility', 'visible');
+        }
     };
-    
+
     $scope.viewHints = function() {
-	if (!$scope.hints) {
-	    return;
-	}
-	
-	$('.lessonHelp').hide();
+        if (!$scope.hints) {
+            return;
+        }
+
+        $('.lessonHelp').hide();
         $('#lesson_hint_row').show();
         goat.utils.scrollToHelp();
-	$scope.curHint = $scope.hints[$scope.hintIndex].hint;
-	$scope.manageHintButtons();
+        $scope.curHint = $scope.hints[$scope.hintIndex].hint;
+        $scope.manageHintButtons();
     };
-    
+
     $scope.viewNextHint = function() {
-	$scope.hintIndex++;
-	$scope.curHint = $scope.hints[$scope.hintIndex].hint;
-	$scope.manageHintButtons();
+        $scope.hintIndex++;
+        $scope.curHint = $scope.hints[$scope.hintIndex].hint;
+        $scope.manageHintButtons();
     };
-    
-    $scope.viewPrevHint = function () {
-	$scope.hintIndex--;
-	$scope.curHint = $scope.hints[$scope.hintIndex].hint;
-	$scope.manageHintButtons();
+
+    $scope.viewPrevHint = function() {
+        $scope.hintIndex--;
+        $scope.curHint = $scope.hints[$scope.hintIndex].hint;
+        $scope.manageHintButtons();
     };
-    
-    $scope.hideHints = function () {
-	
+
+    $scope.hideHints = function() {
+
     };
-    
-    
-    }).animation('.slideDown', function() {
-	var NgHideClassName = 'ng-hide';
-	return {
-	    beforeAddClass: function(element, className, done) {
-		if (className === NgHideClassName) {
-		    $(element).slideUp(done);
-		}
-	    },
-	    removeClass: function(element, className, done) {
-		if (className === NgHideClassName) {
-		    $(element).hide().slideDown(done);
-		}
-	    }
-	};
-	
-	
-    });
+
+    $scope.showAbout = function() {
+        $('#aboutModal').modal({
+            remote: 'about.mvc'
+        });
+    };
+
+
+}).animation('.slideDown', function() {
+    var NgHideClassName = 'ng-hide';
+    return {
+        beforeAddClass: function(element, className, done) {
+            if (className === NgHideClassName) {
+                $(element).slideUp(done);
+            }
+        },
+        removeClass: function(element, className, done) {
+            if (className === NgHideClassName) {
+                $(element).hide().slideDown(done);
+            }
+        }
+    };
+
+
+});