Merge pull request #228 from span/developer-controls
Developer controls
This commit is contained in:
commit
a8f8d4b4fa
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -71,10 +71,10 @@
|
||||
<li role="presentation" class="divider"></li>
|
||||
<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" 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>
|
||||
|
||||
<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>
|
||||
|
@ -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
|
||||
========================================================================== */
|
||||
|
@ -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'));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
||||
});
|
||||
});
|
@ -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() {
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user