Reset lesson bug (#741)

* Remove old code from UI

* Remove old code

* Remove old functions

* Remove unnecessary divs

* Remove logging to console

* Clear lesson messages (checkmark, output text etc) when lesson resets
This commit is contained in:
Nanne Baars 2020-01-05 20:22:50 +01:00 committed by René Zubcevic
parent 5de82c0a06
commit edd6b7d7cf
26 changed files with 9 additions and 832 deletions

View File

@ -1,74 +0,0 @@
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
*/
package org.owasp.webgoat.service;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* <p>LessonPlanService class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
//TODO remove
public class LessonPlanService {
private final WebSession webSession;
public LessonPlanService(WebSession webSession) {
this.webSession = webSession;
}
/**
* Returns source for current attack
*
* @return a {@link java.lang.String} object.
*/
@RequestMapping(path = "/service/lessonplan.mvc", produces = "application/html")
public @ResponseBody
String showPlan() {
String plan = getPlan();
return plan;
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
protected String getPlan() {
return "Plan is not available for this lesson.";
}
}

View File

@ -31,30 +31,6 @@ public class LessonProgressService {
private UserTrackerRepository userTrackerRepository; private UserTrackerRepository userTrackerRepository;
private WebSession webSession; private WebSession webSession;
/**
* <p>LessonProgressService.</p>
*
* @return a {@link LessonInfoModel} object.
*/
@RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json")
@ResponseBody
public Map getLessonInfo() {
Map json = new HashMap();
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
if (webSession.getCurrentLesson() != null) {
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
String successMessage = "";
boolean lessonCompleted = false;
if (lessonTracker != null) {
lessonCompleted = isLessonComplete(lessonTracker.getLessonOverview(), webSession.getCurrentLesson());
successMessage = "LessonCompleted"; //@todo we still use this??
}
json.put("lessonCompleted", lessonCompleted);
json.put("successMessage", successMessage);
}
return json;
}
/** /**
* Endpoint for fetching the complete lesson overview which informs the user about whether all the assignments are solved. * Endpoint for fetching the complete lesson overview which informs the user about whether all the assignments are solved.
* Used as the last page of the lesson to generate a lesson overview. * Used as the last page of the lesson to generate a lesson overview.

View File

@ -1,67 +0,0 @@
/**
* *************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at
* https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/
package org.owasp.webgoat.service;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
* <p>PluginReloadService class.</p>
*
* @author nbaars
* @version $Id: $Id
*/
//TODO REMOVE?
@Controller
public class PluginReloadService {
/**
* Reload all the plugins
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.springframework.http.ResponseEntity} object.
*/
@RequestMapping(path = "/service/reloadplugins.mvc", produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
ResponseEntity<Map<String, Object>> reloadPlugins(HttpSession session) {
Map<String, Object> result = new HashMap<String, Object>();
result.put("success", true);
result.put("message", "Plugins reloaded");
return new ResponseEntity<>(result, HttpStatus.OK);
}
}

View File

@ -3,22 +3,13 @@ define(['jquery',
'libs/backbone', 'libs/backbone',
'goatApp/model/LessonContentModel', 'goatApp/model/LessonContentModel',
'goatApp/view/LessonContentView', 'goatApp/view/LessonContentView',
// 'goatApp/view/PlanView',
// 'goatApp/view/SourceView',
// 'goatApp/view/SolutionView',
'goatApp/view/HintView', 'goatApp/view/HintView',
'goatApp/view/HelpControlsView', 'goatApp/view/HelpControlsView',
'goatApp/view/ParamView',
'goatApp/model/ParamModel',
'goatApp/view/DeveloperControlsView',
'goatApp/support/GoatUtils', 'goatApp/support/GoatUtils',
'goatApp/view/UserAndInfoView', 'goatApp/view/UserAndInfoView',
'goatApp/view/MenuButtonView', 'goatApp/view/MenuButtonView',
'goatApp/model/LessonInfoModel', 'goatApp/model/LessonInfoModel',
'goatApp/view/TitleView', 'goatApp/view/TitleView'
'goatApp/model/LessonProgressModel',
'goatApp/view/LessonProgressView',
'goatApp/view/LessonOverviewView'
], ],
function($, function($,
_, _,
@ -27,27 +18,18 @@ define(['jquery',
LessonContentView, LessonContentView,
HintView, HintView,
HelpControlsView, HelpControlsView,
ParamView,
ParamModel,
DeveloperControlsView,
GoatUtils, GoatUtils,
UserAndInfoView, UserAndInfoView,
MenuButtonView, MenuButtonView,
LessonInfoModel, LessonInfoModel,
TitleView, TitleView
LessonProgressModel,
LessonProgressView,
LessonOverviewView
) { ) {
'use strict' 'use strict'
var Controller = function(options) { var Controller = function(options) {
this.lessonContent = new LessonContentModel(); this.lessonContent = new LessonContentModel();
this.lessonProgressModel = new LessonProgressModel();
this.lessonProgressView = new LessonProgressView(this.lessonProgressModel);
this.lessonContentView = options.lessonContentView; this.lessonContentView = options.lessonContentView;
this.titleView = options.titleView; this.titleView = options.titleView;
this.developerControlsView = new DeveloperControlsView();
_.extend(Controller.prototype,Backbone.Events); _.extend(Controller.prototype,Backbone.Events);
@ -107,7 +89,6 @@ define(['jquery',
this.listenTo(this.helpControlsView,'hints:show',this.showHintsView); this.listenTo(this.helpControlsView,'hints:show',this.showHintsView);
this.listenTo(this.helpControlsView,'lesson:restart',this.restartLesson); this.listenTo(this.helpControlsView,'lesson:restart',this.restartLesson);
this.listenTo(this.developerControlsView, 'dev:labels', this.restartLesson);
this.helpControlsView.render(); this.helpControlsView.render();
this.showHintsView(); this.showHintsView();
@ -129,18 +110,9 @@ define(['jquery',
//TODO: consider moving hintView as child of lessonContentView ... //TODO: consider moving hintView as child of lessonContentView ...
this.createLessonHintView(); this.createLessonHintView();
//TODO: instantiate model with values (not sure why was not working before)
var paramModel = new ParamModel({});
paramModel.set('scrParam',this.lessonContent.get('scrParam'));
paramModel.set('menuParam',this.lessonContent.get('menuParam'));
paramModel.set('stageParam',this.lessonContent.get('stageParam'));
paramModel.set('numParam',this.lessonContent.get('numParam'));
this.paramView = new ParamView({model:paramModel});
$('.lesson-help').hide(); $('.lesson-help').hide();
} }
//this.trigger('menu:reload'); //this.trigger('menu:reload');
this.lessonProgressModel.completed();
}; };
this.createLessonHintView = function () { this.createLessonHintView = function () {
@ -177,6 +149,7 @@ define(['jquery',
self.loadLesson(self.name); self.loadLesson(self.name);
self.updateMenu(); self.updateMenu();
self.callPaginationUpdate(); self.callPaginationUpdate();
self.lessonContentView.resetLesson();
}); });
}; };
@ -191,8 +164,5 @@ define(['jquery',
}; };
return Controller; return Controller;
}); });

View File

@ -32,7 +32,6 @@ define([
labelStatusLoaded: function(data) { labelStatusLoaded: function(data) {
this.enabled = data.enabled; this.enabled = data.enabled;
this.label = this.enabled ? this.labels['disable'] : this.labels['enable']; this.label = this.enabled ? this.labels['disable'] : this.labels['enable'];
this.trigger('plugins:loaded', this, data);
} }
}); });

View File

@ -1,17 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/HTMLContentModel'],
function($,
_,
Backbone,
HTMLContentModel) {
return HTMLContentModel.extend({
url:'service/lessonplan.mvc',
checkNullModel: function() {
if (this.get('content').indexOf('Could not find lesson plan for') > -1) {
this.set('content',null);
}
}
});
});

View File

@ -1,13 +0,0 @@
define(['jquery',
'underscore',
'backbone'],
function ($,
_,
Backbone) {
return Backbone.Model.extend({
url: 'service/lessonprogress.mvc',
completed: function () {
this.fetch();
}
});
});

View File

@ -1,12 +0,0 @@
define([
'backbone'],
function(
Backbone) {
return Backbone.Model.extend({
initialize: function(options) {
for (var key in options) {
this.set(key, options.key);
}
}
});
});

View File

@ -1,19 +0,0 @@
define([
'backbone'],
function(
Backbone) {
return Backbone.Model.extend({
url: 'service/reloadplugins.mvc',
id: 'reload-plugins',
label: 'Reload plugins',
load: function () {
this.fetch().then(this.pluginsLoaded.bind(this));
},
pluginsLoaded: function(data) {
this.trigger('plugins:loaded', this, data);
}
});
});

View File

@ -1,18 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/HTMLContentModel'],
function($,
_,
Backbone,
HTMLContentModel) {
return HTMLContentModel.extend({
url:'service/solution.mvc',
checkNullModel: function() {
if (this.get('content').indexOf('Could not find the solution file or solution file does not exist') === 0) {
this.set('content',null);
}
}
});
});

View File

@ -1,19 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/HTMLContentModel'],
function($,
_,
Backbone,
HTMLContentModel) {
return HTMLContentModel.extend({
url:'service/source.mvc',
checkNullModel: function () {
//TODO: move this function into HTMLContentModel and make the string a property of this 'child' model
if (this.get('content').indexOf("Could not find the source file or") > -1) {
this.set('content',null);
}
}
});
});

View File

@ -1,77 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/PluginReloadModel',
'goatApp/model/LabelDebugModel'],
function(
$,
_,
Backbone,
PluginReloadModel,
LabelDebugModel) {
return Backbone.View.extend({
el: '#developer-controls',
onControlClick: function(model) {
$('#' + model.id).find('td').text('Loading...');
model.load();
},
onPluginsLoaded: function(model) {
window.location.href = 'welcome.mvc';
},
onLabelsLoaded: function(model) {
this.models[1] = model;
this.render();
this.trigger('dev:labels')
},
initialize: function(options) {
this.addMenuListener();
this.models = [new PluginReloadModel(), new LabelDebugModel()];
this.listenTo(this.models[0], 'plugins:loaded', this.onPluginsLoaded);
this.listenTo(this.models[1], 'plugins:loaded', this.onLabelsLoaded);
this.render();
},
addMenuListener: function() {
var showHandler = function(e) {
e.preventDefault();
$('#developer-control-container').show();
$(this).text('Hide developer controls').off().on('click', hideHandler);
};
var hideHandler = function(e) {
e.preventDefault();
$('#developer-control-container').hide();
$(this).text('Show developer controls').off().on('click', showHandler);
};
$('a[href="#developer-controls"]').click(showHandler);
},
render: function() {
this.$el.html('');
var table = $('<table>',{'class':'developer-controls-table table-nonfluid'});
var self = this;
_.each(this.models, function(model) {
var newRow = $('<tr>', { id: model.id });
var headerCell = $('<th>')
var statusCell = $('<td>')
var link = $('<a>', {
'text': model.label,
'title': model.label
});
link.click(_.bind(self.onControlClick, self, model));
newRow.append(headerCell.append(link));
newRow.append(statusCell);
table.append(newRow);
});
this.$el.append(table);
}
});
});

View File

@ -7,7 +7,6 @@ define(['jquery',
'goatApp/controller/MenuController', 'goatApp/controller/MenuController',
'goatApp/view/LessonContentView', 'goatApp/view/LessonContentView',
'goatApp/view/MenuView', 'goatApp/view/MenuView',
'goatApp/view/DeveloperControlsView',
'goatApp/view/TitleView' 'goatApp/view/TitleView'
], function ($, ], function ($,
$vuln, $vuln,
@ -18,7 +17,6 @@ define(['jquery',
MenuController, MenuController,
LessonContentView, LessonContentView,
MenuView, MenuView,
DeveloperControlsView,
TitleView) { TitleView) {
function getContentElement() { function getContentElement() {

View File

@ -41,14 +41,6 @@ function($,_,Backbone) {
this.trigger('hints:show','hint'); this.trigger('hints:show','hint');
}, },
showSource: function() {
this.trigger('source:show','source');
},
showSolution: function() {
this.trigger('solution:show','solution');
},
restartLesson: function() { restartLesson: function() {
this.trigger('lesson:restart'); this.trigger('lesson:restart');
} }

View File

@ -1,23 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/SourceModel'],
function($,
_,
Backbone,
SourceModel) {
return Backbone.View.extend({
el:'#lessonHelpWrapper .lessonHelp.lessonPlan', //Check this
initialize: function() {
this.model = new SourceModel();
this.listenTo(this.model,'loaded',this.onModelLoaded);
this.model.loadData();
},
render:function(title) {
},
onModelLoaded: function() {
this.trigger(this.loadedMessage,this.helpElement);
}
});
});

View File

@ -79,7 +79,6 @@ function($,
self.hintsToShow.push(hintModel.get('hint')); self.hintsToShow.push(hintModel.get('hint'));
} }
}); });
console.log(this.hintsToShow);
}, },
onModelLoaded: function() { onModelLoaded: function() {

View File

@ -186,7 +186,6 @@ define(['jquery',
for (var i=0; i<pageForms.length; i++) { for (var i=0; i<pageForms.length; i++) {
endpoints.push(pageForms[i].action); endpoints.push(pageForms[i].action);
} }
console.log(endpoints);
return endpoints; return endpoints;
}, },
@ -208,6 +207,12 @@ define(['jquery',
/* for testing */ /* for testing */
showTestParam: function (param) { showTestParam: function (param) {
this.$el.find('.lesson-content').html('test:' + param); this.$el.find('.lesson-content').html('test:' + param);
},
resetLesson: function() {
this.$el.find('.attack-feedback').hide();
this.$el.find('.attack-output').hide();
this.markAssignmentIncomplete();
} }
}); });

View File

@ -1,57 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/LessonOverviewCollection',
'text!templates/lesson_overview.html'],
function($,
_,
Backbone,
LessonOverviewCollection,
LessonOverviewTemplate) {
return Backbone.View.extend({
template: LessonOverviewTemplate,
el:'#lesson-overview',
initialize: function (lessonOverviewCollection) {
this.collection = lessonOverviewModel;
this.listenTo(this.collection, 'change add remove update reset', this.render);
this.hideLessonOverview();
},
events: {
"click a": "clickedAssignment"
},
clickedAssignment: function(e){
e.preventDefault();
var id = $(e.currentTarget).data("id");
Backbone.trigger('assignment:navTo',{'assignment': id});
},
showAssignments: function() {
this.$el.html('');
var t = _.template(this.template);
this.$el.html(t({"assignments" : this.model.toJSON()}));
},
render: function() {
if (this.isVisible()) {
this.$el.hide();
} else {
this.$el.show();
}
//this.showAssignments();
return this;
},
isVisible: function() {
return this.$el.is(':visible');
},
hideLessonOverview: function() {
if (this.$el.is(':visible')) {
this.$el.hide();
}
}
});
});

View File

@ -1,26 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/LessonProgressModel'],
function ($,
_,
Backbone,
LessonProgressModel) {
return Backbone.View.extend({
el: '#lesson-progress',
initialize: function (lessonProgressModel) {
this.model = lessonProgressModel;
if (this.model) {
this.listenTo(this.model, 'change', this.render);
}
},
render: function () {
if (this.model.get("assignmentCompleted")) {
this.$el.html(this.model.get('successMessage'));
} else {
this.$el.html("");
}
}
});
});

View File

@ -1,14 +0,0 @@
define(['jquery',
'underscore',
'backbone'], function($,_,Backbone) {
return Backbone.View.extend({
initialize: function(options) {
options = options || {};
}
});
});

View File

@ -1,36 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/ParamModel'],
function($,
_,
Backbone,
ParamModel) {
return Backbone.View.extend({
el:'#params-view',
initialize: function(options) {
this.model = options.model;
if (options.model) {
this.listenTo(this.model,'change',this.render);
}
this.render();
},
render: function() {
this.$el.html('');
var paramsTable = $('<table>',{'class':'param-table table-striped table-nonfluid'});
var self = this;
_.each(this.model.keys(), function(attribute) {
var attributeLabel = attribute.replace(/Param/,'');
var newRow = $('<tr>');
newRow.append($('<th>',{text:_.escape(attributeLabel)}))
newRow.append($('<td>',{text:_.escape(self.model.get(attribute))}));
paramsTable.append(newRow);
});
this.$el.append($('<h4>',{text:'Parameters'}));
this.$el.append(paramsTable);
}
});
});

View File

@ -1,25 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/LessonPlanModel'],
function($,
_,
Backbone,
LessonPlanModel) {
return Backbone.View.extend({
el:'#lessonHelpWrapper .lessonHelp.lessonPlan', //Check this
initialize: function() {
this.model = new LessonPlanModel();
this.listenTo(this.model,'loaded',this.onModelLoaded);
this.model.loadData();
},
render:function(title) {
},
onModelLoaded: function() {
this.trigger('plan:loaded',{'helpElement':'plan','value':true});
}
});
});

View File

@ -1,22 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/SolutionModel'],
//TODO: create a base 'HelpView class'
function($,_,Backbone,SolutionModel) {
return Backbone.View.extend({
el:'#lessonHelpWrapper .lessonHelp.lessonSolution', //Check this
initialize: function() {
this.model = new SolutionModel();
this.listenTo(this.model,'loaded',this.onModelLoaded);
this.model.loadData();
//TODO: handle error cases
},
render:function(title) {
},
onModelLoaded: function() {
this.trigger('solution:loaded',{'helpElement':'solution','value':true});
}
});
});

View File

@ -1,21 +0,0 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/SourceModel',
'goatApp/view/HelpView'],
function($,
_,
Backbone,
SourceModel,
HelpView) {
return HelpView.extend({
helpElement:{'helpElement':'source','value':true},
loadedMessage:'source:loaded',
el:'#lessonHelpWrapper .lessonHelp.lessonPlan', //Check this
initialize: function() {
this.model = new SourceModel();
this.listenTo(this.model,'loaded',this.onModelLoaded);
this.model.loadData();
}
});
});

View File

@ -1,189 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta http-equiv="Expires" CONTENT="-1"/>
<meta http-equiv="Pragma" CONTENT="no-cache"/>
<meta http-equiv="Cache-Control" CONTENT="no-cache"/>
<meta http-equiv="Cache-Control" CONTENT="no-store"/>
<!--[if lt IE 7]>
<id class="no-js lt-ie9 lt-ie8 lt-ie7"/> <![endif]-->
<!--[if IE 7]>
<id class="no-js lt-ie9 lt-ie8"/> <![endif]-->
<!--[if IE 8]>
<id class="no-js lt-ie9"/> <![endif]-->
<!--[if gt IE 8]><!-->
<!-- CSS -->
<link rel="shortcut icon" th:href="@{/images/favicon.ico}" type="image/x-icon"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/main.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/plugins/bootstrap/css/bootstrap.min.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/font-awesome.min.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/animate.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/coderay.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/css/lessons.css}"/>
<!-- end of CSS -->
<!-- JS -->
<script src="js/modernizr-2.6.2.min.js"/>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"/>
<script src="js/respond.min.js"/>
<![endif]-->
<!-- Require.js used to load js asynchronously -->
<script src="js/libs/require.min.js" data-main="js/main.js"/>
<meta http-equiv="Content-Type" content="text/id; charset=ISO-8859-1"/>
<title>WebGoat</title>
</head>
<body>
<section id="container">
<header id="header">
<!--logo start-->
<div class="brand">
<a th:href="@{/welcome.mvc}" class="logo"><span>Web</span>Goat</a>
</div>
<!--logo end-->
<div class="toggle-navigation toggle-left">
<button type="button" class="btn btn-default" id="toggle-menu" data-toggle="tooltip" data-placement="right"
title="Toggle Navigation">
<i class="fa fa-bars"></i>
</button>
</div><!--toggle navigation end-->
<div id="lesson-title-wrapper">
</div><!--lesson title end-->
<div class="user-nav pull-right" id="user-and-info-nav" style="margin-right: 75px;">
<div class="dropdown" style="display:inline">
<button type="button" data-toggle="dropdown" class="btn btn-default dropdown-toggle" id="user-menu">
<i class="fa fa-user"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-left">
<li role="presentation"><a role="menuitem" tabindex="-1" th:href="@{/logout}"
th:text="#{logout}">Logout</a></li>
<li role="presentation" class="divider"></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: <span
th:text="${#authentication.name}"></span></a>
</li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Role:
<span sec:authorize="hasAuthority('WEBGOAT_USER')">User</span>
<span sec:authorize="hasAuthority('WEBGOAT_ADMIN')">Admin</span>
</a>
</li>
<li role="presentation" class="divider"></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#"
th:text="#{version}">Version: <span
th:text="${@environment.getProperty('webgoat.build.version')}"></span></a>
</li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#"
th:text="#{build}">Build:
<span th:text="${@environment.getProperty('webgoat.build.number')}"></span></a></li>
</ul>
</div>
<div style="display:inline" id="settings">
<!--<button type="button" id="admin-button" class="btn btn-default right_nav_button" title="Administrator">-->
<!--<i class="fa fa-cog"></i>-->
<!--</button>-->
<button type="button" id="report-card-button" class="btn btn-default right_nav_button button-up"
th:title="#{report.card}">
<a href="#reportCard"><i class="fa fa-bar-chart-o"></i></a>
</button>
<!--<button type="button" id="user-management" class="btn btn-default right_nav_button"-->
<!--title="User management">-->
<!--<i class="fa fa-users"></i>-->
<!--</button>-->
</div>
<button type="button" id="about-button" class="btn btn-default right_nav_button" th:title="#{about}"
data-toggle="modal" data-target="#about-modal">
<i class="fa fa-info"></i>
</button>
<a href="mailto:${contactEmail}?Subject=Webgoat%20feedback" target="_top">
<button type="button" class="btn btn-default right_nav_button" data-toggle="tooltip"
th:title="#{contact}">
<i class="fa fa-envelope"></i>
</button>
</a>
</div>
</header>
<aside class="sidebar">
<div id="menu-container"></div>
</aside>
<!--sidebar left end-->
<!--main content start-->
<section class="main-content-wrapper">
<section id="main-content"> <!--ng-controller="goatLesson"-->
<div id="lesson-page" class="pages">
<span th:text="${numUsers}"></span>
<span> Users in WebGoat</span>
<div sec:authorize="hasAuthority('WEBGOAT_ADMIN')">
<h3>WebGoat Users</h3>
<div th:each="user : ${allUsers}">
<span th:text="${user.username}" />
<ul>Hash: <span th:text="${user.userHash}" /></ul>
<ul>Admin: <span th:text="${user.admin}" /></ul>
</div>
</div>
<div id="lesson-helps-wrapper" class="panel">
<div class="lesson-help" id="lesson-plan-row">
<div class="col-md-12">
<h4>Lesson Plan</h4>
<div class="panel">
<div class="panel-body" id="lesson-plan-content">
<!-- allowing jQuery to handle this one -->
</div>
</div>
</div>
</div>
<div class="lesson-help" id="lesson-solution-row">
<div class="col-md-12">
<h4>Lesson Solution</h4>
<div class="panel">
<div class="panel-body" id="lesson-solution-content">
</div>
</div>
</div>
</div>
<div class="lesson-help" id="lesson-source-row">
<div class="col-md-12">
<h4>Lesson Source Code</h4>
<div class="panel">
<div class="panel-body" id="lesson-source-content">
</div>
</div>
</div>
</div>
</div>
</div>
<div id="report-card-page" class="pages" style="display: none;">
</div>
</section>
</section>
</section>
<!-- About WebGoat Modal -->
<div class="modal" id="about-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content" th:replace="about :: about"></div>
</div>
</div>
</body>
</html>

View File

@ -182,39 +182,6 @@
</div> </div>
</div> </div>
</div> </div>
<div id="lesson-helps-wrapper" class="panel">
<div class="lesson-help" id="lesson-plan-row">
<div class="col-md-12">
<h4>Lesson Plan</h4>
<div class="panel">
<div class="panel-body" id="lesson-plan-content">
<!-- allowing jQuery to handle this one -->
</div>
</div>
</div>
</div>
<div class="lesson-help" id="lesson-solution-row">
<div class="col-md-12">
<h4>Lesson Solution</h4>
<div class="panel">
<div class="panel-body" id="lesson-solution-content">
</div>
</div>
</div>
</div>
<div class="lesson-help" id="lesson-source-row">
<div class="col-md-12">
<h4>Lesson Source Code</h4>
<div class="panel">
<div class="panel-body" id="lesson-source-content">
</div>
</div>
</div>
</div>
</div>
</div> </div>
<div id="report-card-page" class="pages" style="display: none;"> <div id="report-card-page" class="pages" style="display: none;">
</div> </div>