Fix ReCaptha NPE

Improve error handling when permission are removed.
This commit is contained in:
Paulo Gustavo Veiga 2012-09-06 23:52:53 -03:00
parent 743164ade4
commit 337a67a8f6
12 changed files with 84 additions and 24 deletions

View File

@ -45,7 +45,8 @@ mindplot.RESTPersistenceManager = new Class({
events.onError(); events.onError();
}, },
onFailure:function (xhr) { onFailure:function (xhr) {
events.onError(); var responseText = xhr.responseText;
events.onError(JSON.decode(responseText));
}, },
headers:{"Content-Type":"application/json", "Accept":"application/json"}, headers:{"Content-Type":"application/json", "Accept":"application/json"},
emulation:false, emulation:false,
@ -60,7 +61,6 @@ mindplot.RESTPersistenceManager = new Class({
async:false, async:false,
method:'post', method:'post',
onSuccess:function () { onSuccess:function () {
console.log("Revert success ....");
}, },
onException:function () { onException:function () {
}, },

View File

@ -78,10 +78,14 @@ mindplot.widget.IMenu = new Class({
} }
menu.setRequireChange(false); menu.setRequireChange(false);
}, },
onError:function () { onError:function (error) {
if (saveHistory) { if (saveHistory) {
saveElem.setStyle('cursor', 'pointer'); saveElem.setStyle('cursor', 'pointer');
$notify($msg('SAVE_COULD_NOT_BE_COMPLETED')); var msg = error ? error.globalErrors : null;
if (!msg) {
msg = $msg('SAVE_COULD_NOT_BE_COMPLETED');
}
$notify(msg);
} }
} }
}); });

View File

@ -18,11 +18,21 @@
package com.wisemapping.exceptions; package com.wisemapping.exceptions;
import org.jetbrains.annotations.NotNull;
public class AccessDeniedSecurityException public class AccessDeniedSecurityException
extends Exception extends ClientException
{ {
public AccessDeniedSecurityException(String msg) public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED";
public AccessDeniedSecurityException(@NotNull String msg)
{ {
super(msg); super(msg);
} }
@NotNull
@Override
protected String getMsgBundleKey() {
return MSG_KEY;
}
} }

View File

@ -0,0 +1,20 @@
package com.wisemapping.exceptions;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.MessageSource;
import java.util.Locale;
abstract public class ClientException extends WiseMappingException {
public ClientException(@NotNull String message) {
super(message);
}
protected abstract
@NotNull
String getMsgBundleKey();
public String getMessage(@NotNull final MessageSource messageSource, final @NotNull Locale locale) {
return messageSource.getMessage(this.getMsgBundleKey(), null, locale);
}
}

View File

@ -18,6 +18,7 @@
package com.wisemapping.model; package com.wisemapping.model;
import com.wisemapping.exceptions.AccessDeniedSecurityException;
import com.wisemapping.exceptions.WiseMappingException; import com.wisemapping.exceptions.WiseMappingException;
import com.wisemapping.util.ZipUtils; import com.wisemapping.util.ZipUtils;
import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringEscapeUtils;
@ -233,7 +234,7 @@ public class Mindmap {
final Collaboration collaboration = this.findCollaboration(collaborator); final Collaboration collaboration = this.findCollaboration(collaborator);
if (collaboration == null) { if (collaboration == null) {
throw new WiseMappingException("User is not collaborator"); throw new AccessDeniedSecurityException("Collaborator " + collaborator.getEmail() + " could not access " + this.getId());
} }
return collaboration.getCollaborationProperties(); return collaboration.getCollaborationProperties();
} }

View File

@ -137,10 +137,16 @@ public class UsersController {
final String challenge = request.getParameter("recaptcha_challenge_field"); final String challenge = request.getParameter("recaptcha_challenge_field");
final String uresponse = request.getParameter("recaptcha_response_field"); final String uresponse = request.getParameter("recaptcha_response_field");
final String remoteAddr = request.getRemoteAddr(); if (challenge != null && uresponse != null) {
final ReCaptchaResponse reCaptchaResponse = captchaService.checkAnswer(remoteAddr, challenge, uresponse); final String remoteAddr = request.getRemoteAddr();
if (!reCaptchaResponse.isValid()) { final ReCaptchaResponse reCaptchaResponse = captchaService.checkAnswer(remoteAddr, challenge, uresponse);
bindingResult.rejectValue("captcha", Messages.CAPTCHA_ERROR);
if (!reCaptchaResponse.isValid()) {
bindingResult.rejectValue("captcha", Messages.CAPTCHA_ERROR);
}
} else {
bindingResult.rejectValue("captcha", Messages.CAPTCHA_LOADING_ERROR);
} }
} }
return bindingResult; return bindingResult;

View File

@ -60,7 +60,7 @@ public class AdminController extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = "admin/users", consumes = {"application/xml", "application/json"}, produces = {"application/json", "text/html", "application/xml"}) @RequestMapping(method = RequestMethod.POST, value = "admin/users", consumes = {"application/xml", "application/json"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.CREATED) @ResponseStatus(value = HttpStatus.CREATED)
public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws IOException, WiseMappingException { public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws WiseMappingException {
if (user == null) { if (user == null) {
throw new IllegalArgumentException("User could not be found"); throw new IllegalArgumentException("User could not be found");
} }
@ -90,7 +90,7 @@ public class AdminController extends BaseController {
@RequestMapping(method = RequestMethod.PUT, value = "admin/users/{id}/password", consumes = {"text/plain"}) @RequestMapping(method = RequestMethod.PUT, value = "admin/users/{id}/password", consumes = {"text/plain"})
@ResponseStatus(value = HttpStatus.NO_CONTENT) @ResponseStatus(value = HttpStatus.NO_CONTENT)
public void changePassword(@RequestBody String password, @PathVariable long id) throws IOException, WiseMappingException { public void changePassword(@RequestBody String password, @PathVariable long id) throws WiseMappingException {
if (password == null) { if (password == null) {
throw new IllegalArgumentException("Password can not be null"); throw new IllegalArgumentException("Password can not be null");
} }
@ -105,7 +105,7 @@ public class AdminController extends BaseController {
@RequestMapping(method = RequestMethod.DELETE,value = "admin/users/{id}") @RequestMapping(method = RequestMethod.DELETE,value = "admin/users/{id}")
@ResponseStatus(value = HttpStatus.NO_CONTENT) @ResponseStatus(value = HttpStatus.NO_CONTENT)
public void getUserByEmail(@PathVariable long id) throws IOException, WiseMappingException { public void getUserByEmail(@PathVariable long id) throws WiseMappingException {
final User user = userService.getUserBy(id); final User user = userService.getUserBy(id);
if (user == null) { if (user == null) {
throw new IllegalArgumentException("User '" + id + "' could not be found"); throw new IllegalArgumentException("User '" + id + "' could not be found");

View File

@ -19,6 +19,7 @@
package com.wisemapping.rest; package com.wisemapping.rest;
import com.wisemapping.exceptions.AccessDeniedSecurityException; import com.wisemapping.exceptions.AccessDeniedSecurityException;
import com.wisemapping.exceptions.ClientException;
import com.wisemapping.filter.UserAgent; import com.wisemapping.filter.UserAgent;
import com.wisemapping.mail.NotificationService; import com.wisemapping.mail.NotificationService;
import com.wisemapping.model.User; import com.wisemapping.model.User;
@ -27,6 +28,7 @@ import com.wisemapping.security.Utils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
@ -36,6 +38,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
import java.util.Locale;
public class BaseController { public class BaseController {
@ -75,13 +78,20 @@ public class BaseController {
@ExceptionHandler(java.lang.reflect.UndeclaredThrowableException.class) @ExceptionHandler(java.lang.reflect.UndeclaredThrowableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public RestErrors handleSecurityErrors(@NotNull UndeclaredThrowableException ex) { public RestErrors handleSecurityErrors(@NotNull UndeclaredThrowableException ex) {
return new RestErrors(ex.getMessage()); final Throwable cause = ex.getCause();
RestErrors result;
if (cause instanceof ClientException) {
result = handleClientErrors((ClientException) cause);
} else {
result = new RestErrors(ex.getMessage());
}
return result;
} }
@ExceptionHandler(com.wisemapping.exceptions.AccessDeniedSecurityException.class) @ExceptionHandler(ClientException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public RestErrors handleSecurityException(@NotNull AccessDeniedSecurityException ex) { public RestErrors handleClientErrors(@NotNull ClientException ex) {
return new RestErrors(ex.getMessage()); final Locale locale = LocaleContextHolder.getLocale();
return new RestErrors(ex.getMessage(messageSource, locale));
} }
} }

View File

@ -30,7 +30,7 @@ public class RestErrors {
private Errors errors; private Errors errors;
@JsonIgnore @JsonIgnore
private List<String> globalErrors; private List<String> gErrors;
@JsonIgnore @JsonIgnore
MessageSource messageSource; MessageSource messageSource;
@ -43,12 +43,12 @@ public class RestErrors {
this.errors = errors; this.errors = errors;
this.messageSource = messageSource; this.messageSource = messageSource;
this.globalErrors = this.processGlobalErrors(errors, messageSource); this.gErrors = this.processGlobalErrors(errors, messageSource);
} }
public RestErrors(@NotNull String errorMsg) { public RestErrors(@NotNull String errorMsg) {
globalErrors = new ArrayList<String>(); gErrors = new ArrayList<String>();
globalErrors.add(errorMsg); gErrors.add(errorMsg);
} }
private List<String> processGlobalErrors(@NotNull Errors errors, @NotNull MessageSource messageSource) { private List<String> processGlobalErrors(@NotNull Errors errors, @NotNull MessageSource messageSource) {
@ -61,7 +61,7 @@ public class RestErrors {
} }
public List<String> getGlobalErrors() { public List<String> getGlobalErrors() {
return globalErrors; return gErrors;
} }
public void setGlobalErrors(List<String> list) { public void setGlobalErrors(List<String> list) {

View File

@ -26,4 +26,5 @@ public interface Messages {
String MAP_TITLE_ALREADY_EXISTS = "MAP_TITLE_ALREADY_EXISTS"; String MAP_TITLE_ALREADY_EXISTS = "MAP_TITLE_ALREADY_EXISTS";
String PASSWORD_MISSMATCH = "PASSWORD_MISSMATCH"; String PASSWORD_MISSMATCH = "PASSWORD_MISSMATCH";
String CAPTCHA_ERROR = "CAPTCHA_ERROR"; String CAPTCHA_ERROR = "CAPTCHA_ERROR";
String CAPTCHA_LOADING_ERROR = "CAPTCHA_LOADING_ERROR";
} }

View File

@ -241,6 +241,10 @@ SUPPORT=Support
FEEDBACK=Feedback FEEDBACK=Feedback
CONTACT_US=Contact Us CONTACT_US=Contact Us
#Pending for translation ...
CAPTCHA_LOADING_ERROR=ReCaptcha could not be loaded. You must have access to Google ReCaptcha service.
ACCESS_HAS_BEEN_REVOKED= Upps. your access permissions to this map has been revoked. Contact map owner.

View File

@ -241,3 +241,7 @@ FEEDBACK=Feedback
CONTACT_US=Contáctenos CONTACT_US=Contáctenos
ACCESS_HAS_BEEN_REVOKED=Los permisos de acceso al mapa han sido revocados. No es posible grabar sus cambios.