Issue #160: Provide Async Error Handling
Added Toast notification for unexpected errors On 401 and 403 Errors, user is redirected to login
This commit is contained in:
parent
e5ed24fcf7
commit
feb38eef8c
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* *************************************************************************************************
|
||||||
|
* <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;
|
||||||
|
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>LabelService class.</p>
|
||||||
|
*
|
||||||
|
* @author zupzup
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AjaxAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
||||||
|
public AjaxAuthenticationEntryPoint(String loginFormUrl) {
|
||||||
|
super(loginFormUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||||
|
if(request.getHeader("x-requested-with") != null) {
|
||||||
|
response.sendError(401, authException.getMessage());
|
||||||
|
} else {
|
||||||
|
super.commence(request, response, authException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -68,6 +68,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
security.and().csrf().disable();
|
security.and().csrf().disable();
|
||||||
|
|
||||||
http.headers().cacheControl().disable();
|
http.headers().cacheControl().disable();
|
||||||
|
http.exceptionHandling().authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//// TODO: 11/18/2016 make this a little bit more configurabe last part at least
|
//// TODO: 11/18/2016 make this a little bit more configurabe last part at least
|
||||||
|
@ -978,3 +978,22 @@ font-size: 1.3em;
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ERROR NOTIFICATION */
|
||||||
|
#error-notification-container {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
width: 35%;
|
||||||
|
|
||||||
|
}
|
||||||
|
#error-notification {
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #eb6154;
|
||||||
|
border-color: #eb6154;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
define(['jquery','underscore','backbone','goatApp/view/GoatRouter'],
|
define(['jquery','underscore','backbone','goatApp/view/GoatRouter', 'goatApp/support/goatAsyncErrorHandler'],
|
||||||
function($,_,Backbone,Router){
|
function($,_,Backbone,Router, asyncErrorHandler){
|
||||||
'use strict'
|
'use strict'
|
||||||
//var goatRouter = new Router();
|
//var goatRouter = new Router();
|
||||||
return {
|
return {
|
||||||
initApp: function() {
|
initApp: function() {
|
||||||
|
asyncErrorHandler.init();
|
||||||
//TODO: add query/ability to load from where they left off
|
//TODO: add query/ability to load from where they left off
|
||||||
var goatRouter = new Router();
|
var goatRouter = new Router();
|
||||||
goatRouter.init();
|
goatRouter.init();
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
define(
|
||||||
|
['backbone', 'underscore'],
|
||||||
|
function(Backbone, _) {
|
||||||
|
return {
|
||||||
|
init: function() {
|
||||||
|
var backboneSync = Backbone.sync;
|
||||||
|
|
||||||
|
var asyncErrorHandler = function(error) {
|
||||||
|
return function(jqXHR) {
|
||||||
|
var statusCode = jqXHR.status;
|
||||||
|
var errorCodes = {
|
||||||
|
404: true,
|
||||||
|
500: true,
|
||||||
|
503: true,
|
||||||
|
504: true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (statusCode === 401 || statusCode === 403) {
|
||||||
|
window.top.location.href = "login";
|
||||||
|
} else if(errorCodes[statusCode]) {
|
||||||
|
Backbone.trigger("error:unhandled");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Backbone.sync = function(method, model, options) {
|
||||||
|
// override error handler
|
||||||
|
options.error = asyncErrorHandler(options.error);
|
||||||
|
return backboneSync(method, model, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
@ -0,0 +1,35 @@
|
|||||||
|
define(['jquery',
|
||||||
|
'underscore',
|
||||||
|
'backbone'],
|
||||||
|
function($,
|
||||||
|
_,
|
||||||
|
Backbone) {
|
||||||
|
return Backbone.View.extend({
|
||||||
|
el:'#error-notification-container',
|
||||||
|
initialize: function() {
|
||||||
|
Backbone.on("error:unhandled", this.showNotification.bind(this));
|
||||||
|
this.hideNotification();
|
||||||
|
this.currentTimeout = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
showNotification: function() {
|
||||||
|
var self = this;
|
||||||
|
if (!this.$el.is(':visible')) {
|
||||||
|
this.$el.show(350);
|
||||||
|
}
|
||||||
|
if (this.currentTimeout != null) {
|
||||||
|
window.clearTimeout(this.currentTimeout);
|
||||||
|
}
|
||||||
|
this.currentTimeout = window.setTimeout(function() {
|
||||||
|
self.hideNotification();
|
||||||
|
self.currentTimeout = null;
|
||||||
|
}, 3000);
|
||||||
|
},
|
||||||
|
|
||||||
|
hideNotification: function() {
|
||||||
|
if (this.$el.is(':visible')) {
|
||||||
|
this.$el.hide(350);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -2,17 +2,20 @@
|
|||||||
define(['jquery',
|
define(['jquery',
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'libs/jquery.form'],
|
'libs/jquery.form',
|
||||||
|
'goatApp/view/ErrorNotificationView'],
|
||||||
function(
|
function(
|
||||||
$,
|
$,
|
||||||
_,
|
_,
|
||||||
Backbone,
|
Backbone,
|
||||||
JQueryForm) {
|
JQueryForm,
|
||||||
|
ErrorNotificationView) {
|
||||||
return Backbone.View.extend({
|
return Backbone.View.extend({
|
||||||
el:'#lesson-content-wrapper', //TODO << get this fixed up in DOM
|
el:'#lesson-content-wrapper', //TODO << get this fixed up in DOM
|
||||||
|
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
new ErrorNotificationView();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* initial renering */
|
/* initial renering */
|
||||||
|
@ -111,6 +111,11 @@
|
|||||||
<!--</div>-->
|
<!--</div>-->
|
||||||
<div class="col-md-12" align="left">
|
<div class="col-md-12" align="left">
|
||||||
<div id="lesson-content-wrapper" class="panel">
|
<div id="lesson-content-wrapper" class="panel">
|
||||||
|
<div class="" id="error-notification-container">
|
||||||
|
<div class="" id="error-notification">
|
||||||
|
<i class="fa fa-exclamation-circle" /> There was an unexpected error. Please try again.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="" id="help-controls">
|
<div class="" id="help-controls">
|
||||||
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-source-button">
|
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-source-button">
|
||||||
<i class="fa fa-code" />
|
<i class="fa fa-code" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user