Improve error handle on security errors.

This commit is contained in:
Paulo Gustavo Veiga 2022-03-15 10:30:18 -03:00
parent 4cab5299c4
commit a9d091a187
6 changed files with 64 additions and 107 deletions

View File

@ -1,33 +1,37 @@
/* /*
* Copyright [2015] [wisemapping] * Copyright [2015] [wisemapping]
* *
* Licensed under WiseMapping Public License, Version 1.0 (the "License"). * Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the * It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page; * "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the license at * You may obtain a copy of the license at
* *
* http://www.wisemapping.org/license * http://www.wisemapping.org/license
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.wisemapping.exceptions; package com.wisemapping.exceptions;
import com.wisemapping.model.Collaborator;
import com.wisemapping.model.User;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class AccessDeniedSecurityException public class AccessDeniedSecurityException
extends ClientException extends ClientException {
{
public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED"; public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED";
public AccessDeniedSecurityException(@NotNull String msg) public AccessDeniedSecurityException(@NotNull String msg) {
{ super(msg, Severity.FATAL);
super(msg,Severity.FATAL); }
public AccessDeniedSecurityException(@NotNull long mapId, Collaborator user) {
super("No enough permissions to access map. Id: " + mapId + ", User: " + user, Severity.FATAL);
} }
@NotNull @NotNull

View File

@ -1,43 +0,0 @@
package com.wisemapping.mail;
import com.wisemapping.model.User;
import com.wisemapping.security.Utils;
import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.Set;
public class NotifyingExceptionResolver extends SimpleMappingExceptionResolver {
final private Logger logger = Logger.getLogger(NotifyingExceptionResolver.class);
private Set<String> exclude = new HashSet<String>();
private NotificationService notificationService;
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
if (!exclude.contains(ex.getClass().getName())) {
logger.error("An Exception has occurred in the application", ex);
sendNotification(ex, request);
}
return super.doResolveException(request, response, handler, ex);
}
private void sendNotification(@NotNull Exception ex, @NotNull HttpServletRequest request) {
final User user = Utils.getUser(false);
notificationService.reportJavaException(ex, user, request);
}
public void setExclude(final Set<String> exclude) {
this.exclude = exclude;
}
public void setNotificationService(NotificationService notificationService) {
this.notificationService = notificationService;
}
}

View File

@ -250,7 +250,7 @@ public class MindmapController extends BaseController {
// Has enough permissions ? // Has enough permissions ?
final User user = Utils.getUser(); final User user = Utils.getUser();
if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) { if (!mindmapService.hasPermissions(user, id, CollaborationRole.VIEWER)) {
throw new AccessDeniedSecurityException("No enough permissions to open map. Id:" + id); throw new AccessDeniedSecurityException(id, user);
} }
// Does the map exists ? // Does the map exists ?

View File

@ -1,20 +1,20 @@
/* /*
* Copyright [2015] [wisemapping] * Copyright [2015] [wisemapping]
* *
* Licensed under WiseMapping Public License, Version 1.0 (the "License"). * Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the * It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page; * "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the license at * You may obtain a copy of the license at
* *
* http://www.wisemapping.org/license * http://www.wisemapping.org/license
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.wisemapping.service; package com.wisemapping.service;
@ -31,20 +31,20 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/* /*
* Refresh page should not lost the lock. * Refresh page should not lost the lock.
* En caso que no sea posible grabar por que se perdio el lock, usar mensaje de error para explicar el por que... * En caso que no sea posible grabar por que se perdio el lock, usar mensaje de error para explicar el por que...
* Mensaje modal explicando que el mapa esta siendo editado, por eso no es posible edilarlo.... * Mensaje modal explicando que el mapa esta siendo editado, por eso no es posible edilarlo....
* Internacionalizacion de los mensaje ... * Internacionalizacion de los mensaje ...
* Logout limpiar las sessiones ... * Logout limpiar las sessiones ...
* *
* Casos: * Casos:
* - Usuario pierde el lock: * - Usuario pierde el lock:
* - Y grabo con la misma sessions y el timestap ok. * - Y grabo con la misma sessions y el timestap ok.
* - Y grabo con la misma session y el timestap esta mal * - Y grabo con la misma session y el timestap esta mal
* - Y grabo con distinta sessions * - Y grabo con distinta sessions
* - * -
* - Usuario pierde el lock, pero intenta grabar camio * - Usuario pierde el lock, pero intenta grabar camio
*/ */
class LockManagerImpl implements LockManager { class LockManagerImpl implements LockManager {
public static final int ONE_MINUTE_MILLISECONDS = 1000 * 60; public static final int ONE_MINUTE_MILLISECONDS = 1000 * 60;
@ -97,7 +97,7 @@ class LockManagerImpl implements LockManager {
} }
if (!mindmap.hasPermissions(user, CollaborationRole.EDITOR)) { if (!mindmap.hasPermissions(user, CollaborationRole.EDITOR)) {
throw new AccessDeniedSecurityException("Invalid lock, this should not happen"); throw new AccessDeniedSecurityException(mindmap.getId(), user);
} }
this.unlock(mindmap.getId()); this.unlock(mindmap.getId());
@ -132,7 +132,7 @@ class LockManagerImpl implements LockManager {
} }
if (!mindmap.hasPermissions(user, CollaborationRole.EDITOR)) { if (!mindmap.hasPermissions(user, CollaborationRole.EDITOR)) {
throw new AccessDeniedSecurityException("Invalid lock, this should not happen"); throw new AccessDeniedSecurityException(mindmap.getId(), user);
} }
LockInfo result = lockInfoByMapId.get(mindmap.getId()); LockInfo result = lockInfoByMapId.get(mindmap.getId());

View File

@ -176,7 +176,7 @@ public class MindmapController {
private MindMapBean findMindmapBean(int mapId) throws MapCouldNotFoundException, AccessDeniedSecurityException { private MindMapBean findMindmapBean(int mapId) throws MapCouldNotFoundException, AccessDeniedSecurityException {
final User user = Utils.getUser(); final User user = Utils.getUser();
if (!mindmapService.hasPermissions(user, mapId, CollaborationRole.VIEWER)) { if (!mindmapService.hasPermissions(user, mapId, CollaborationRole.VIEWER)) {
throw new AccessDeniedSecurityException("No enough permissions to open map with id " + mapId); throw new AccessDeniedSecurityException(mapId, user);
} }
final Mindmap mindmap = findMindmap(mapId); final Mindmap mindmap = findMindmap(mapId);

View File

@ -22,29 +22,25 @@
<bean id="requestInterceptor" class="com.wisemapping.filter.RequestPropertiesInterceptor"/> <bean id="requestInterceptor" class="com.wisemapping.filter.RequestPropertiesInterceptor"/>
</mvc:interceptors> </mvc:interceptors>
<bean id="exceptionHandlerResolver" <bean id="simpleMappingExceptionResolver"
class="com.wisemapping.mail.NotifyingExceptionResolver"> class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultStatusCode" value="500"/> <property name="defaultStatusCode" value="500"/>
<property name="defaultErrorView" value="unexpectedError"/> <property name="defaultErrorView" value="unexpectedError"/>
<property name="warnLogCategory" value="com.wisemapping.mvc.Exceptions"/>
<property name="exceptionMappings"> <property name="exceptionMappings">
<props> <props>
<!-- Security exceptions are wrapped in this exceptions --> <!-- Security access exceptions must not handled as unexpected errors -->
<prop key="com.wisemapping.exceptions.MapNonPublicException">securityError</prop>
<prop key="com.wisemapping.exceptions.AccessDeniedSecurityException">securityError</prop> <prop key="com.wisemapping.exceptions.AccessDeniedSecurityException">securityError</prop>
</props> </props>
</property> </property>
<property name="statusCodes"> <property name="statusCodes">
<props> <props>
<prop key="securityError">404</prop> <prop key="securityError">403</prop>
</props> </props>
</property> </property>
<property name="exclude">
<set>
<value>java.lang.reflect.UndeclaredThrowableException</value>
</set>
</property>
<property name="notificationService" ref="notificationService"/>
</bean> </bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">