From 6508a634fc741a92504a59ef95c24ea576f73284 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer <paul-christian.volkmer@mni.thm.de> Date: Tue, 16 Oct 2012 16:46:58 +0200 Subject: [PATCH] Use exceptions instead of checking for null to send correct http code If a session was not found in database this will result in http 404, if the session is not accessable for the current user the request will result in http 403. The old behavior was to check for null. This was the response if the session was not found or the current user could not access this session (not owner and inactive sessions). Both ended up with http 404 - not found. --- .../de/thm/arsnova/SessionController.java | 14 +++++++---- .../java/de/thm/arsnova/dao/CouchDBDao.java | 6 +++-- .../exceptions/ForbiddenException.java | 5 ++++ .../arsnova/exceptions/NotFoundException.java | 5 ++++ .../controller/SessionControllerTest.java | 24 +++++++++++++++---- .../de/thm/arsnova/dao/StubDatabaseDao.java | 19 ++++++++++++++- 6 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 src/main/java/de/thm/arsnova/exceptions/ForbiddenException.java create mode 100644 src/main/java/de/thm/arsnova/exceptions/NotFoundException.java diff --git a/src/main/java/de/thm/arsnova/SessionController.java b/src/main/java/de/thm/arsnova/SessionController.java index fff51bb9..fa046818 100644 --- a/src/main/java/de/thm/arsnova/SessionController.java +++ b/src/main/java/de/thm/arsnova/SessionController.java @@ -39,6 +39,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; +import de.thm.arsnova.exceptions.ForbiddenException; +import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.ISessionService; import de.thm.arsnova.services.IUserService; import de.thm.arsnova.socket.ARSnovaSocketIOServer; @@ -73,10 +75,14 @@ public class SessionController { @RequestMapping(value="/session/{sessionkey}", method=RequestMethod.GET) @ResponseBody public Session getSession(@PathVariable String sessionkey, HttpServletResponse response) { - Session session = sessionService.getSession(sessionkey); - if (session != null) return session; - - response.setStatus(HttpStatus.NOT_FOUND.value()); + try { + Session session = sessionService.getSession(sessionkey); + if (session != null) return session; + } catch (NotFoundException e) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + } catch (ForbiddenException e) { + response.setStatus(HttpStatus.FORBIDDEN.value()); + } return null; } diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index e6175ad6..28ba1b8c 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -51,6 +51,8 @@ import com.fourspaces.couchdb.ViewResults; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; +import de.thm.arsnova.exceptions.ForbiddenException; +import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.ISessionService; import de.thm.arsnova.services.IUserService; import de.thm.arsnova.socket.message.Question; @@ -148,14 +150,14 @@ public class CouchDBDao implements IDatabaseDao { public Session getSession(String keyword) { Session result = this.getSessionFromKeyword(keyword); if(result == null) { - return null; + throw new NotFoundException(); } if (result.isActive() || result.getCreator().equals(this.actualUserName())) { sessionService.addUserToSessionMap(this.actualUserName(), keyword); return result; } - return null; + throw new ForbiddenException(); } @Override diff --git a/src/main/java/de/thm/arsnova/exceptions/ForbiddenException.java b/src/main/java/de/thm/arsnova/exceptions/ForbiddenException.java new file mode 100644 index 00000000..8f1f74d5 --- /dev/null +++ b/src/main/java/de/thm/arsnova/exceptions/ForbiddenException.java @@ -0,0 +1,5 @@ +package de.thm.arsnova.exceptions; + +public class ForbiddenException extends RuntimeException { + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/de/thm/arsnova/exceptions/NotFoundException.java b/src/main/java/de/thm/arsnova/exceptions/NotFoundException.java new file mode 100644 index 00000000..caca267d --- /dev/null +++ b/src/main/java/de/thm/arsnova/exceptions/NotFoundException.java @@ -0,0 +1,5 @@ +package de.thm.arsnova.exceptions; + +public class NotFoundException extends RuntimeException { + private static final long serialVersionUID = 1L; +} diff --git a/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java b/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java index 74804a30..b1204794 100644 --- a/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java +++ b/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java @@ -1,6 +1,7 @@ package de.thm.arsnova.controller; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import javax.inject.Inject; @@ -19,6 +20,7 @@ import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; import de.thm.arsnova.SessionController; +import de.thm.arsnova.exceptions.NotFoundException; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={ @@ -45,16 +47,30 @@ public class SessionControllerTest { } @Test - public void testShouldNotGetMissingSession() { + public void testShouldNotGetUnknownSession() { request.setMethod("GET"); - request.setRequestURI("/session/12345678"); + request.setRequestURI("/session/00000000"); try { final ModelAndView mav = handlerAdapter.handle(request, response, sessionController); assertNull(mav); + assertTrue(response.getStatus() == 404); } catch (Exception e) { e.printStackTrace(); fail("An exception occured"); } - - } + } + + @Test + public void testShouldNotGetForbiddenSession() { + request.setMethod("GET"); + request.setRequestURI("/session/99999999"); + try { + final ModelAndView mav = handlerAdapter.handle(request, response, sessionController); + assertNull(mav); + assertTrue(response.getStatus() == 403); + } catch (Exception e) { + e.printStackTrace(); + fail("An exception occured"); + } + } } diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index 3026b3ee..a893fb60 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -4,12 +4,16 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; +import de.thm.arsnova.exceptions.ForbiddenException; +import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.socket.message.Question; @Component @@ -20,6 +24,8 @@ public class StubDatabaseDao implements IDatabaseDao { private Map<String, Feedback> stubFeedbacks = new ConcurrentHashMap<String, Feedback>(); private Map<Session, Question> stubQuestions = new ConcurrentHashMap<Session, Question>(); + private final Logger logger = LoggerFactory.getLogger(getClass()); + public StubDatabaseDao() { fillWithDummySessions(); fillWithDummyFeedbacks(); @@ -56,7 +62,13 @@ public class StubDatabaseDao implements IDatabaseDao { @Override public Session getSession(String keyword) { - return stubSessions.get(keyword); + // Magic keyword for forbidden session + if (keyword.equals("99999999")) throw new ForbiddenException(); + + Session session = stubSessions.get(keyword); + if (session == null) throw new NotFoundException(); + + return session; } @Override @@ -108,4 +120,9 @@ public class StubDatabaseDao implements IDatabaseDao { return stubQuestions.get(session) != null; } + @Override + public Question getQuestion(String id) { + // Simply ... no such question ;-) + return null; + } } -- GitLab