Merge pull request #228 from span/developer-controls

Developer controls
This commit is contained in:
Nanne 2016-04-08 18:27:29 +02:00
commit a8f8d4b4fa
11 changed files with 306 additions and 25 deletions

View File

@ -29,18 +29,23 @@
*/
package org.owasp.webgoat.service;
import java.util.HashMap;
import java.util.Map;
import org.owasp.webgoat.session.LabelDebugger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* <p>PluginReloadService class.</p>
* <p>LabelDebugService class.</p>
*
* @author nbaars
* @version $Id: $Id
@ -48,21 +53,52 @@ import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LabelDebugService extends BaseService {
private static final String URL_DEBUG_LABELS_MVC = "/debug/labels.mvc";
private static final String KEY_ENABLED = "enabled";
private static final String KEY_SUCCESS = "success";
private static final Logger logger = LoggerFactory.getLogger(LabelDebugService.class);
@Autowired
private LabelDebugger labelDebugger;
/**
* Reload all the plugins
* Checks if debugging of labels is enabled or disabled
*
* @return a {@link org.springframework.http.ResponseEntity} object.
*/
@RequestMapping(value = "/debug/labels.mvc")
@RequestMapping(value = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
//todo parse params to add enable / disable
ResponseEntity<String> reloadPlugins() {
labelDebugger.enable();
return new ResponseEntity("Label debugger enabled refresh the WebGoat page!",HttpStatus.OK);
ResponseEntity<Map<String, Object>> checkDebuggingStatus() {
logger.debug("Checking label debugging, it is " + labelDebugger.isEnabled()); // FIXME parameterize
Map<String, Object> result = createResponse(labelDebugger.isEnabled());
return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
}
/**
* Sets the enabled flag on the label debugger to the given parameter
*
* @return a {@link org.springframework.http.ResponseEntity} object.
* @throws Exception
*/
@RequestMapping(value = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE, params = KEY_ENABLED)
public @ResponseBody
ResponseEntity<Map<String, Object>> setDebuggingStatus(@RequestParam("enabled") Boolean enabled) throws Exception {
logger.debug("Setting label debugging to " + labelDebugger.isEnabled()); // FIXME parameterize
Map<String, Object> result = createResponse(enabled);
labelDebugger.setEnabled(enabled);
return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
}
/**
* @param enabled
* @return a {@link java.util.Map} object.
*/
private Map<String, Object> createResponse(Boolean enabled) {
Map<String, Object> result = new HashMap<String, Object>();
result.put(KEY_SUCCESS, Boolean.TRUE);
result.put(KEY_ENABLED, enabled);
return result;
}
}

View File

@ -29,19 +29,23 @@
*/
package org.owasp.webgoat.service;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.nio.file.Paths;
/**
* <p>PluginReloadService class.</p>
*
@ -59,16 +63,20 @@ public class PluginReloadService extends BaseService {
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.springframework.http.ResponseEntity} object.
*/
@RequestMapping(value = "/reloadplugins.mvc")
@RequestMapping(value = "/reloadplugins.mvc", produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
ResponseEntity<String> reloadPlugins(HttpSession session) {
ResponseEntity<Map<String, Object>> reloadPlugins(HttpSession session) {
WebSession webSession = (WebSession) session.getAttribute(WebSession.SESSION);
logger.debug("Loading plugins into cache");
String pluginPath = session.getServletContext().getRealPath("plugin_lessons");
String targetPath = session.getServletContext().getRealPath("plugin_extracted");
new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).copyJars();
webSession.getCourse().loadLessonFromPlugin(session.getServletContext());
return new ResponseEntity("Plugins reload refresh the WebGoat page!",HttpStatus.OK);
Map<String, Object> result = new HashMap<String, Object>();
result.put("success", true);
result.put("message", "Plugins reloaded");
return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
}
}

View File

@ -10,7 +10,7 @@ import java.io.Serializable;
*/
public class LabelDebugger implements Serializable {
private boolean isEnabled = false;
private boolean enabled = false;
/**
* <p>isEnabled.</p>
@ -18,14 +18,31 @@ public class LabelDebugger implements Serializable {
* @return a boolean.
*/
public boolean isEnabled() {
return isEnabled;
return enabled;
}
/**
* <p>enable.</p>
* <p>Enables label debugging</p>
*/
public void enable() {
this.isEnabled = true;
this.enabled = true;
}
/**
* <p>Disables label debugging</p>
*/
public void disable() {
this.enabled = false;
}
/**
* <p>Sets the status to enabled</p>
* @param enabled
* @throws Exception if enabled is null
*/
public void setEnabled(Boolean enabled) throws Exception {
if(enabled == null) throw new Exception("Cannot set enabled to null");
this.enabled = enabled;
}
}

View File

@ -72,9 +72,9 @@
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: ${user}</a></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Role: ${role}</a></li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="#developer-controls">Show developer controls</a></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">${version}</a></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Build: ${build}</a></li>
</ul>
</div>
<button type="button" id="about-button" class="btn btn-default right_nav_button" title="About WebGoat" data-toggle="modal" data-target="#about-modal">
@ -143,6 +143,15 @@
<h4>Params</h4>
</div>
</div>
<div id="developer-control-container">
<div align="left">
<h3>Developer controls</h3>
</div>
<hr />
<div id="developer-controls">
</div>
</div>
</div>
</div>
</div>

View File

@ -765,6 +765,27 @@ cookie-container {
padding-left:3px;
}
.developer-controls-table {
width: 100%;
}
.developer-controls-table td {
text-align: right;
}
.developer-controls-table a {
color: #e84c3d
}
#developer-control-container {
display: none;
}
#menu-container a,
.developer-controls-table a {
cursor: pointer;
}
/* ==========================================================================
MENU / Sidebar
========================================================================== */

View File

@ -123,6 +123,7 @@ define(['jquery',
this.sourceView = new SourceView();
this.lessonHintView = new HintView();
this.cookieView = new CookieView();
//TODO: instantiate model with values (not sure why was not working before)
var paramModel = new ParamModel({});
paramModel.set('scrParam',this.lessonContent.get('scrParam'));

View File

@ -0,0 +1,39 @@
define([
'backbone'],
function(
Backbone) {
return Backbone.Model.extend({
id: 'label-status',
url: 'service/debug/labels.mvc',
label: '',
labels: {
enable: 'Enable label debugging',
disable: 'Disable label debugging'
},
initialize: function() {
this.load();
},
fetch: function(options) {
options || (options = {});
var data = (options.data || {});
if(this.enabled != undefined) {
options.data = { enabled: !this.enabled };
}
return Backbone.Collection.prototype.fetch.call(this, options);
},
load: function () {
this.fetch().then(this.labelStatusLoaded.bind(this));
},
labelStatusLoaded: function(data) {
this.enabled = data.enabled;
this.label = this.enabled ? this.labels['disable'] : this.labels['enable'];
this.trigger('plugins:loaded', this, data);
}
});
});

View File

@ -0,0 +1,19 @@
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

@ -0,0 +1,77 @@
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();
Backbone.history.loadUrl(Backbone.history.getFragment());
},
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

@ -4,17 +4,20 @@ define(['jquery',
'goatApp/controller/LessonController',
'goatApp/controller/MenuController',
'goatApp/view/LessonContentView',
'goatApp/view/MenuView'
'goatApp/view/MenuView',
'goatApp/view/DeveloperControlsView'
], function ($,
_,
Backbone,
LessonController,
MenuController,
LessonContentView,
MenuView) {
MenuView,
DeveloperControlsView) {
var lessonView = new LessonContentView();
var menuView = new MenuView();
var developerControlsView = new DeveloperControlsView();
var GoatAppRouter = Backbone.Router.extend({
routes: {
@ -25,11 +28,11 @@ define(['jquery',
},
lessonController: new LessonController({
lessonView:lessonView
lessonView: lessonView
}),
menuController: new MenuController({
menuView:menuView
menuView: menuView
}),
init:function() {

View File

@ -0,0 +1,51 @@
package org.owasp.webgoat.session;
import org.junit.Assert;
import org.junit.Test;
public class LabelDebuggerTest {
@Test
public void testSetEnabledTrue() throws Exception {
LabelDebugger ld = new LabelDebugger();
ld.setEnabled(true);
Assert.assertTrue(ld.isEnabled());
}
@Test
public void testSetEnabledFalse() throws Exception {
LabelDebugger ld = new LabelDebugger();
ld.setEnabled(false);
Assert.assertFalse(ld.isEnabled());
}
@Test
public void testSetEnabledNullThrowsException() {
LabelDebugger ld = new LabelDebugger();
try {
ld.setEnabled(null);
} catch (Exception e) {
// We want to end up here
return;
}
Assert.fail();
}
@Test
public void testEnableIsTrue() {
LabelDebugger ld = new LabelDebugger();
ld.enable();
Assert.assertTrue(ld.isEnabled());
}
@Test
public void testDisableIsFalse() {
LabelDebugger ld = new LabelDebugger();
ld.disable();
Assert.assertFalse(ld.isEnabled());
}
}