From 87bf2db6b03404c4a465100fa421ecdf65a0747b Mon Sep 17 00:00:00 2001
From: Paul-Christian Volkmer <paul-christian.volkmer@mni.thm.de>
Date: Mon, 2 Jun 2014 09:12:54 +0200
Subject: [PATCH] Do not throw ForbiddenException, use security implementation
 instead

---
 .../java/de/thm/arsnova/dao/CouchDBDao.java   | 580 +++++++++---------
 .../ApplicationPermissionEvaluator.java       |  11 +-
 .../thm/arsnova/services/SessionService.java  |  99 ++-
 .../arsnova/services/SessionServiceTest.java  |  13 +
 4 files changed, 359 insertions(+), 344 deletions(-)

diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 5b1da08b..850d7262 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -58,7 +58,6 @@ import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.entities.VisitedSession;
-import de.thm.arsnova.exceptions.ForbiddenException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.services.ISessionService;
 
@@ -76,47 +75,44 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Value("${couchdb.host}")
 	public final void setDatabaseHost(final String newDatabaseHost) {
-		this.databaseHost = newDatabaseHost;
+		databaseHost = newDatabaseHost;
 	}
 
 	@Value("${couchdb.port}")
 	public final void setDatabasePort(final String newDatabasePort) {
-		this.databasePort = Integer.parseInt(newDatabasePort);
+		databasePort = Integer.parseInt(newDatabasePort);
 	}
 
 	@Value("${couchdb.name}")
 	public final void setDatabaseName(final String newDatabaseName) {
-		this.databaseName = newDatabaseName;
+		databaseName = newDatabaseName;
 	}
 
 	public final void setSessionService(final ISessionService service) {
-		this.sessionService = service;
+		sessionService = service;
 	}
 
 	@Override
 	public final Session getSession(final String keyword) {
-		Session result = this.getSessionFromKeyword(keyword);
-		if (result == null) {
-			throw new NotFoundException();
-		}
-		if (result.isActive()) {
+		final Session result = getSessionFromKeyword(keyword);
+		if (result != null && result.isActive()) {
 			return result;
 		}
 
-		throw new ForbiddenException();
+		throw new NotFoundException();
 	}
 
 	@Override
 	public final List<Session> getMySessions(final User user) {
-		NovaView view = new NovaView("session/by_creator");
+		final NovaView view = new NovaView("session/by_creator");
 		view.setStartKeyArray(user.getUsername());
 		view.setEndKeyArray(user.getUsername(), "{}");
 
-		ViewResults sessions = this.getDatabase().view(view);
+		final ViewResults sessions = getDatabase().view(view);
 
-		List<Session> result = new ArrayList<Session>();
-		for (Document d : sessions.getResults()) {
-			Session session = (Session) JSONObject.toBean(
+		final List<Session> result = new ArrayList<Session>();
+		for (final Document d : sessions.getResults()) {
+			final Session session = (Session) JSONObject.toBean(
 					d.getJSONObject().getJSONObject("value"),
 					Session.class
 					);
@@ -129,7 +125,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public final List<Question> getSkillQuestions(User user, Session session) {
+	public final List<Question> getSkillQuestions(final User user, final Session session) {
 		String viewName;
 		if (session.getCreator().equals(user.getUsername())) {
 			viewName = "skill_question/by_session_sorted_by_subject_and_text";
@@ -150,9 +146,9 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final Session getSessionFromKeyword(final String keyword) {
-		NovaView view = new NovaView("session/by_keyword");
+		final NovaView view = new NovaView("session/by_keyword");
 		view.setKey(keyword);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 
 		if (results.getJSONArray("rows").optJSONObject(0) == null) {
 			return null;
@@ -165,10 +161,10 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final Session getSessionFromId(final String sessionId) {
-		NovaView view = new NovaView("session/by_id");
+		final NovaView view = new NovaView("session/by_id");
 		view.setKey(sessionId);
 
-		ViewResults sessions = this.getDatabase().view(view);
+		final ViewResults sessions = getDatabase().view(view);
 
 		if (sessions.getJSONArray("rows").optJSONObject(0) == null) {
 			return null;
@@ -181,7 +177,7 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final Session saveSession(final User user, final Session session) {
-		Document sessionDocument = new Document();
+		final Document sessionDocument = new Document();
 		sessionDocument.put("type", "session");
 		sessionDocument.put("name", session.getName());
 		sessionDocument.put("shortName", session.getShortName());
@@ -192,23 +188,23 @@ public class CouchDBDao implements IDatabaseDao {
 		sessionDocument.put("courseId", session.getCourseId());
 		try {
 			database.saveDocument(sessionDocument);
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			return null;
 		}
-		return this.getSession(sessionDocument.getString("keyword"));
+		return getSession(sessionDocument.getString("keyword"));
 	}
 
 	@Override
 	@Transactional(isolation = Isolation.READ_COMMITTED)
 	public final boolean sessionKeyAvailable(final String keyword) {
-		View view = new View("session/by_keyword");
-		ViewResults results = this.getDatabase().view(view);
+		final View view = new View("session/by_keyword");
+		final ViewResults results = getDatabase().view(view);
 
 		return !results.containsKey(keyword);
 	}
 
 	private String getSessionKeyword(final String internalSessionId) throws IOException {
-		Document document = this.getDatabase().getDocument(internalSessionId);
+		final Document document = getDatabase().getDocument(internalSessionId);
 		if (document.has("keyword")) {
 			return (String) document.get("keyword");
 		}
@@ -219,12 +215,12 @@ public class CouchDBDao implements IDatabaseDao {
 	private Database getDatabase() {
 		if (database == null) {
 			try {
-				com.fourspaces.couchdb.Session session = new com.fourspaces.couchdb.Session(
+				final com.fourspaces.couchdb.Session session = new com.fourspaces.couchdb.Session(
 						databaseHost,
 						databasePort
 						);
 				database = session.getDatabase(databaseName);
-			} catch (Exception e) {
+			} catch (final Exception e) {
 				LOGGER.error(
 						"Cannot connect to CouchDB database '" + databaseName
 						+ "' on host '" + databaseHost
@@ -238,20 +234,20 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final Question saveQuestion(final Session session, final Question question) {
-		Document q = toQuestionDocument(session, question);
+		final Document q = toQuestionDocument(session, question);
 		try {
 			database.saveDocument(q);
 			question.set_id(q.getId());
 			question.set_rev(q.getRev());
 			return question;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not save question {}", question);
 		}
 		return null;
 	}
 
 	private Document toQuestionDocument(final Session session, final Question question) {
-		Document q = new Document();
+		final Document q = new Document();
 		q.put("type", "skill_question");
 		q.put("questionType", question.getQuestionType());
 		q.put("questionVariant", question.getQuestionVariant());
@@ -279,7 +275,7 @@ public class CouchDBDao implements IDatabaseDao {
 	@Override
 	public final Question updateQuestion(final Question question) {
 		try {
-			Document q = this.database.getDocument(question.get_id());
+			final Document q = database.getDocument(question.get_id());
 			q.put("subject", question.getSubject());
 			q.put("text", question.getText());
 			q.put("active", question.isActive());
@@ -295,11 +291,11 @@ public class CouchDBDao implements IDatabaseDao {
 			q.put("offsetX", question.getOffsetX());
 			q.put("offsetY", question.getOffsetY());
 			q.put("zoomLvl", question.getZoomLvl());
-			this.database.saveDocument(q);
+			database.saveDocument(q);
 			question.set_rev(q.getRev());
 
 			return question;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not update question {}", question);
 		}
 
@@ -308,7 +304,7 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final InterposedQuestion saveQuestion(final Session session, final InterposedQuestion question) {
-		Document q = new Document();
+		final Document q = new Document();
 		q.put("type", "interposed_question");
 		q.put("sessionId", session.get_id());
 		q.put("subject", question.getSubject());
@@ -321,7 +317,7 @@ public class CouchDBDao implements IDatabaseDao {
 			question.set_rev(q.getRev());
 
 			return question;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not save interposed question {}", question);
 		}
 
@@ -331,29 +327,29 @@ public class CouchDBDao implements IDatabaseDao {
 	@Override
 	public final Question getQuestion(final String id) {
 		try {
-			NovaView view = new NovaView("skill_question/by_id");
+			final NovaView view = new NovaView("skill_question/by_id");
 			view.setKey(id);
-			ViewResults results = this.getDatabase().view(view);
+			final ViewResults results = getDatabase().view(view);
 
 			if (results.getJSONArray("rows").optJSONObject(0) == null) {
 				return null;
 			}
 
-			Question q = (Question) JSONObject.toBean(
+			final Question q = (Question) JSONObject.toBean(
 					results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
 					Question.class
 					);
 			JSONArray possibleAnswers = new JSONArray();
 			possibleAnswers = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value")
 					.getJSONArray("possibleAnswers");
-			Collection<PossibleAnswer> answers = JSONArray.toCollection(
+			final Collection<PossibleAnswer> answers = JSONArray.toCollection(
 					possibleAnswers,
 					PossibleAnswer.class
 					);
 			q.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
-			q.setSessionKeyword(this.getSessionKeyword(q.getSessionId()));
+			q.setSessionKeyword(getSessionKeyword(q.getSessionId()));
 			return q;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not get question with id {}", id);
 		}
 		return null;
@@ -362,17 +358,17 @@ public class CouchDBDao implements IDatabaseDao {
 	@Override
 	public final LoggedIn registerAsOnlineUser(final User user, final Session session) {
 		try {
-			NovaView view = new NovaView("logged_in/all");
+			final NovaView view = new NovaView("logged_in/all");
 			view.setKey(user.getUsername());
-			ViewResults results = this.getDatabase().view(view);
+			final ViewResults results = getDatabase().view(view);
 
 			LoggedIn loggedIn = new LoggedIn();
 			if (results.getJSONArray("rows").optJSONObject(0) != null) {
-				JSONObject json = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value");
+				final JSONObject json = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value");
 				loggedIn = (LoggedIn) JSONObject.toBean(json, LoggedIn.class);
-				JSONArray vs = json.optJSONArray("visitedSessions");
+				final JSONArray vs = json.optJSONArray("visitedSessions");
 				if (vs != null) {
-					Collection<VisitedSession> visitedSessions = JSONArray.toCollection(vs, VisitedSession.class);
+					final Collection<VisitedSession> visitedSessions = JSONArray.toCollection(vs, VisitedSession.class);
 					loggedIn.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions));
 				}
 			}
@@ -382,8 +378,8 @@ public class CouchDBDao implements IDatabaseDao {
 			loggedIn.addVisitedSession(session);
 			loggedIn.updateTimestamp();
 
-			JSONObject json = JSONObject.fromObject(loggedIn);
-			Document doc = new Document(json);
+			final JSONObject json = JSONObject.fromObject(loggedIn);
+			final Document doc = new Document(json);
 			if (doc.getId().isEmpty()) {
 				// If this is a new user without a logged_in document, we have
 				// to remove the following
@@ -393,16 +389,16 @@ public class CouchDBDao implements IDatabaseDao {
 				doc.remove("_id");
 				doc.remove("_rev");
 			}
-			this.getDatabase().saveDocument(doc);
+			getDatabase().saveDocument(doc);
 
-			LoggedIn l = (LoggedIn) JSONObject.toBean(doc.getJSONObject(), LoggedIn.class);
-			JSONArray vs = doc.getJSONObject().optJSONArray("visitedSessions");
+			final LoggedIn l = (LoggedIn) JSONObject.toBean(doc.getJSONObject(), LoggedIn.class);
+			final JSONArray vs = doc.getJSONObject().optJSONArray("visitedSessions");
 			if (vs != null) {
-				Collection<VisitedSession> visitedSessions = JSONArray.toCollection(vs, VisitedSession.class);
+				final Collection<VisitedSession> visitedSessions = JSONArray.toCollection(vs, VisitedSession.class);
 				l.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions));
 			}
 			return l;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			return null;
 		}
 	}
@@ -411,9 +407,9 @@ public class CouchDBDao implements IDatabaseDao {
 	public final void updateSessionOwnerActivity(final Session session) {
 		try {
 			session.setLastOwnerActivity(System.currentTimeMillis());
-			JSONObject json = JSONObject.fromObject(session);
-			this.getDatabase().saveDocument(new Document(json));
-		} catch (IOException e) {
+			final JSONObject json = JSONObject.fromObject(session);
+			getDatabase().saveDocument(new Document(json));
+		} catch (final IOException e) {
 			LOGGER.error("Failed to update lastOwnerActivity for Session {}", session);
 			return;
 		}
@@ -434,62 +430,62 @@ public class CouchDBDao implements IDatabaseDao {
 	@Override
 	public final void deleteQuestionWithAnswers(final Question question) {
 		try {
-			this.deleteAnswers(question);
-			this.deleteDocument(question.get_id());
-		} catch (IOException e) {
+			deleteAnswers(question);
+			deleteDocument(question.get_id());
+		} catch (final IOException e) {
 			LOGGER.error("IOException: Could not delete question {}", question.get_id());
 		}
 	}
 
 	@Override
-	public final void deleteAllQuestionsWithAnswers(Session session) {
-		NovaView view = new NovaView("skill_question/by_session");
+	public final void deleteAllQuestionsWithAnswers(final Session session) {
+		final NovaView view = new NovaView("skill_question/by_session");
 		deleteAllQuestionDocumentsWithAnswers(session, view);
 	}
 
-	private void deleteAllQuestionDocumentsWithAnswers(Session session, NovaView view) {
+	private void deleteAllQuestionDocumentsWithAnswers(final Session session, final NovaView view) {
 		view.setStartKeyArray(session.get_id());
 		view.setEndKey(session.get_id(), "{}");
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 
-		for (Document d : results.getResults()) {
-			Question q = new Question();
+		for (final Document d : results.getResults()) {
+			final Question q = new Question();
 			q.set_id(d.getId());
-			this.deleteQuestionWithAnswers(q);
+			deleteQuestionWithAnswers(q);
 		}
 	}
 
 	private void deleteDocument(final String documentId) throws IOException {
-		Document d = this.getDatabase().getDocument(documentId);
-		this.getDatabase().deleteDocument(d);
+		final Document d = getDatabase().getDocument(documentId);
+		getDatabase().deleteDocument(d);
 	}
 
 	@Override
 	public final void deleteAnswers(final Question question) {
 		try {
-			NovaView view = new NovaView("answer/cleanup");
+			final NovaView view = new NovaView("answer/cleanup");
 			view.setKey(question.get_id());
-			ViewResults results = this.getDatabase().view(view);
+			final ViewResults results = getDatabase().view(view);
 
-			for (Document d : results.getResults()) {
-				this.deleteDocument(d.getId());
+			for (final Document d : results.getResults()) {
+				deleteDocument(d.getId());
 			}
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("IOException: Could not delete answers for question {}", question.get_id());
 		}
 	}
 
 	@Override
 	public final List<String> getUnAnsweredQuestionIds(final Session session, final User user) {
-		NovaView view = new NovaView("answer/by_user");
+		final NovaView view = new NovaView("answer/by_user");
 		view.setKey(user.getUsername(), session.get_id());
-		return collectUnansweredQuestionIds(session, user, this.getQuestionIds(session, user), view);
+		return collectUnansweredQuestionIds(session, user, getQuestionIds(session, user), view);
 	}
 
 	@Override
-	public final Answer getMyAnswer(final User me, final String questionId, int piRound) {
+	public final Answer getMyAnswer(final User me, final String questionId, final int piRound) {
 
-		NovaView view = new NovaView("answer/by_question_and_user_and_piround");
+		final NovaView view = new NovaView("answer/by_question_and_user_and_piround");
 		if (2 == piRound) {
 			view.setKey(questionId, me.getUsername(), "2");
 		} else {
@@ -497,7 +493,7 @@ public class CouchDBDao implements IDatabaseDao {
 			view.setStartKey(questionId, me.getUsername());
 			view.setEndKey(questionId, me.getUsername(), "1");
 		}
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().isEmpty()) {
 			return null;
 		}
@@ -508,8 +504,8 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public final List<Answer> getAnswers(final String questionId, int piRound) {
-		NovaView view = new NovaView("skill_question/count_answers_by_question_and_piround");
+	public final List<Answer> getAnswers(final String questionId, final int piRound) {
+		final NovaView view = new NovaView("skill_question/count_answers_by_question_and_piround");
 		if (2 == piRound) {
 			view.setStartKey(questionId, "2");
 			view.setEndKey(questionId, "2", "{}");
@@ -519,16 +515,16 @@ public class CouchDBDao implements IDatabaseDao {
 			view.setEndKeyArray(questionId, "1", "{}");
 		}
 		view.setGroup(true);
-		ViewResults results = this.getDatabase().view(view);
-		int abstentionCount = this.getAbstentionAnswerCount(questionId);
-		List<Answer> answers = new ArrayList<Answer>();
-		for (Document d : results.getResults()) {
-			Answer a = new Answer();
+		final ViewResults results = getDatabase().view(view);
+		final int abstentionCount = getAbstentionAnswerCount(questionId);
+		final List<Answer> answers = new ArrayList<Answer>();
+		for (final Document d : results.getResults()) {
+			final Answer a = new Answer();
 			a.setAnswerCount(d.getInt("value"));
 			a.setAbstentionCount(abstentionCount);
 			a.setQuestionId(d.getJSONObject().getJSONArray("key").getString(0));
 			a.setPiRound(piRound);
-			String answerText = d.getJSONObject().getJSONArray("key").getString(2);
+			final String answerText = d.getJSONObject().getJSONArray("key").getString(2);
 			a.setAnswerText("null".equals(answerText) ? null : answerText);
 			answers.add(a);
 		}
@@ -536,10 +532,10 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	private int getAbstentionAnswerCount(final String questionId) {
-		NovaView view = new NovaView("skill_question/count_abstention_answers_by_question");
+		final NovaView view = new NovaView("skill_question/count_abstention_answers_by_question");
 		view.setKey(questionId);
 		view.setGroup(true);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().size() == 0) {
 			return 0;
 		}
@@ -548,11 +544,11 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final int getAnswerCount(final Question question, final int piRound) {
-		NovaView view = new NovaView("skill_question/count_total_answers_by_question_and_piround");
+		final NovaView view = new NovaView("skill_question/count_total_answers_by_question_and_piround");
 		view.setGroup(true);
 		view.setStartKey(question.get_id(), String.valueOf(piRound));
 		view.setEndKey(question.get_id(), String.valueOf(piRound), "{}");
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().size() == 0) {
 			return 0;
 		}
@@ -562,34 +558,34 @@ public class CouchDBDao implements IDatabaseDao {
 	@Override
 	public final int countActiveUsers(final long since) {
 		try {
-			View view = new View("statistic/count_active_users");
+			final View view = new View("statistic/count_active_users");
 			view.setStartKey(String.valueOf(since));
-			ViewResults results = this.getDatabase().view(view);
+			final ViewResults results = getDatabase().view(view);
 			if (isEmptyResults(results)) {
 				return 0;
 			}
 			return results.getJSONArray("rows").optJSONObject(0).getInt("value");
-		} catch (Exception e) {
+		} catch (final Exception e) {
 			LOGGER.error("Error while retrieving active users count", e);
 		}
 		return 0;
 	}
 
-	private boolean isEmptyResults(ViewResults results) {
+	private boolean isEmptyResults(final ViewResults results) {
 		return results == null || results.getResults().isEmpty() || results.getJSONArray("rows").size() == 0;
 	}
 
 	@Override
-	public List<Answer> getFreetextAnswers(String questionId) {
-		List<Answer> answers = new ArrayList<Answer>();
-		NovaView view = new NovaView("skill_question/freetext_answers_full");
+	public List<Answer> getFreetextAnswers(final String questionId) {
+		final List<Answer> answers = new ArrayList<Answer>();
+		final NovaView view = new NovaView("skill_question/freetext_answers_full");
 		view.setKey(questionId);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().isEmpty()) {
 			return answers;
 		}
-		for (Document d : results.getResults()) {
-			Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
+		for (final Document d : results.getResults()) {
+			final Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
 			a.setQuestionId(questionId);
 			answers.add(a);
 		}
@@ -598,20 +594,20 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public List<Answer> getMyAnswers(final User me, final String sessionKey) {
-		Session s = this.getSessionFromKeyword(sessionKey);
+		final Session s = getSessionFromKeyword(sessionKey);
 		if (s == null) {
 			throw new NotFoundException();
 		}
 
-		NovaView view = new NovaView("answer/by_user_and_session_full");
+		final NovaView view = new NovaView("answer/by_user_and_session_full");
 		view.setKey(me.getUsername(), s.get_id());
-		ViewResults results = this.getDatabase().view(view);
-		List<Answer> answers = new ArrayList<Answer>();
+		final ViewResults results = getDatabase().view(view);
+		final List<Answer> answers = new ArrayList<Answer>();
 		if (results == null || results.getResults() == null || results.getResults().isEmpty()) {
 			return answers;
 		}
-		for (Document d : results.getResults()) {
-			Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
+		for (final Document d : results.getResults()) {
+			final Answer a = (Answer) JSONObject.toBean(d.getJSONObject().getJSONObject("value"), Answer.class);
 			a.set_id(d.getId());
 			a.set_rev(d.getRev());
 			a.setUser(me.getUsername());
@@ -622,15 +618,15 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getTotalAnswerCount(String sessionKey) {
-		Session s = this.getSessionFromKeyword(sessionKey);
+	public int getTotalAnswerCount(final String sessionKey) {
+		final Session s = getSessionFromKeyword(sessionKey);
 		if (s == null) {
 			throw new NotFoundException();
 		}
 
-		NovaView view = new NovaView("skill_question/count_answers_by_session");
+		final NovaView view = new NovaView("skill_question/count_answers_by_session");
 		view.setKey(s.get_id());
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().size() == 0) {
 			return 0;
 		}
@@ -638,16 +634,16 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getInterposedCount(String sessionKey) {
-		Session s = this.getSessionFromKeyword(sessionKey);
+	public int getInterposedCount(final String sessionKey) {
+		final Session s = getSessionFromKeyword(sessionKey);
 		if (s == null) {
 			throw new NotFoundException();
 		}
 
-		NovaView view = new NovaView("interposed_question/count_by_session");
+		final NovaView view = new NovaView("interposed_question/count_by_session");
 		view.setKey(s.get_id());
 		view.setGroup(true);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.size() == 0 || results.getResults().size() == 0) {
 			return 0;
 		}
@@ -655,16 +651,16 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public InterposedReadingCount getInterposedReadingCount(Session session) {
-		NovaView view = new NovaView("interposed_question/count_by_session_reading");
+	public InterposedReadingCount getInterposedReadingCount(final Session session) {
+		final NovaView view = new NovaView("interposed_question/count_by_session_reading");
 		view.setStartKeyArray(session.get_id());
 		view.setEndKeyArray(session.get_id(), "{}");
 		view.setGroup(true);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.size() == 0 || results.getResults().size() == 0) {
 			return new InterposedReadingCount();
 		}
-		int read = results.getJSONArray("rows").optJSONObject(0).optInt("value");
+		final int read = results.getJSONArray("rows").optJSONObject(0).optInt("value");
 		int unread = 0;
 		if (results.getJSONArray("rows").optJSONObject(1) != null) {
 			unread = results.getJSONArray("rows").optJSONObject(1).optInt("value");
@@ -673,22 +669,22 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public List<InterposedQuestion> getInterposedQuestions(String sessionKey) {
-		Session s = this.getSessionFromKeyword(sessionKey);
+	public List<InterposedQuestion> getInterposedQuestions(final String sessionKey) {
+		final Session s = getSessionFromKeyword(sessionKey);
 		if (s == null) {
 			throw new NotFoundException();
 		}
 
-		NovaView view = new NovaView("interposed_question/by_session");
+		final NovaView view = new NovaView("interposed_question/by_session");
 		view.setKey(s.get_id());
-		ViewResults questions = this.getDatabase().view(view);
+		final ViewResults questions = getDatabase().view(view);
 		if (questions == null || questions.isEmpty()) {
 			return null;
 		}
-		List<InterposedQuestion> result = new ArrayList<InterposedQuestion>();
+		final List<InterposedQuestion> result = new ArrayList<InterposedQuestion>();
 		LOGGER.debug("{}", questions.getResults());
-		for (Document document : questions.getResults()) {
-			InterposedQuestion question = (InterposedQuestion) JSONObject.toBean(
+		for (final Document document : questions.getResults()) {
+			final InterposedQuestion question = (InterposedQuestion) JSONObject.toBean(
 					document.getJSONObject().getJSONObject("value"),
 					InterposedQuestion.class
 					);
@@ -699,17 +695,17 @@ public class CouchDBDao implements IDatabaseDao {
 		return result;
 	}
 
-	public Question getInterposedQuestion(String sessionKey, String documentId) {
+	public Question getInterposedQuestion(final String sessionKey, final String documentId) {
 		try {
-			Document document = this.getDatabase().getDocument(documentId);
+			final Document document = getDatabase().getDocument(documentId);
 			if (document == null) {
 				LOGGER.error("Document is NULL");
 				return null;
 			}
-			Question question = (Question) JSONObject.toBean(document.getJSONObject(), Question.class);
+			final Question question = (Question) JSONObject.toBean(document.getJSONObject(), Question.class);
 			question.setQuestionType("interposed_question");
 			return question;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Error while retrieving interposed question", e);
 		}
 		return null;
@@ -717,40 +713,40 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public void vote(final User me, final String menu) {
-		String date = new SimpleDateFormat("dd-mm-yyyyy").format(new Date());
+		final String date = new SimpleDateFormat("dd-mm-yyyyy").format(new Date());
 		try {
-			NovaView view = new NovaView("food_vote/get_user_vote");
+			final NovaView view = new NovaView("food_vote/get_user_vote");
 			view.setKey(date, me.getUsername());
-			ViewResults results = this.getDatabase().view(view);
+			final ViewResults results = getDatabase().view(view);
 
 			if (results.getResults().isEmpty()) {
-				Document vote = new Document();
+				final Document vote = new Document();
 				vote.put("type", "food_vote");
 				vote.put("name", menu);
 				vote.put("user", me.getUsername());
 				vote.put("day", date);
-				this.database.saveDocument(vote);
+				database.saveDocument(vote);
 			} else {
-				Document vote = results.getResults().get(0);
+				final Document vote = results.getResults().get(0);
 				vote.put("name", menu);
-				this.database.saveDocument(vote);
+				database.saveDocument(vote);
 			}
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Error while saving user food vote", e);
 		}
 	}
 
 	@Override
 	public List<FoodVote> getFoodVote() {
-		List<FoodVote> foodVotes = new ArrayList<FoodVote>();
-		String date = new SimpleDateFormat("dd-mm-yyyyy").format(new Date());
-		NovaView view = new NovaView("food_vote/count_by_day");
+		final List<FoodVote> foodVotes = new ArrayList<FoodVote>();
+		final String date = new SimpleDateFormat("dd-mm-yyyyy").format(new Date());
+		final NovaView view = new NovaView("food_vote/count_by_day");
 		view.setStartKeyArray(date);
 		view.setEndKeyArray(date, "{}");
 		view.setGroup(true);
-		ViewResults results = this.getDatabase().view(view);
-		for (Document d : results.getResults()) {
-			FoodVote vote = new FoodVote();
+		final ViewResults results = getDatabase().view(view);
+		for (final Document d : results.getResults()) {
+			final FoodVote vote = new FoodVote();
 			vote.setCount(d.getJSONObject().optInt("value"));
 			vote.setDay(date);
 			vote.setName(d.getJSONObject().getJSONArray("key").getString(1));
@@ -761,12 +757,12 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public int getFoodVoteCount() {
-		String date = new SimpleDateFormat("dd-mm-yyyyy").format(new Date());
-		NovaView view = new NovaView("food_vote/count_by_day");
+		final String date = new SimpleDateFormat("dd-mm-yyyyy").format(new Date());
+		final NovaView view = new NovaView("food_vote/count_by_day");
 		view.setStartKeyArray(date);
 		view.setEndKeyArray(date, "{}");
 		view.setGroup(false);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.size() == 0 || results.getResults().size() == 0) {
 			return 0;
 		}
@@ -799,21 +795,21 @@ public class CouchDBDao implements IDatabaseDao {
 		return sessionsCountValue("questions");
 	}
 
-	private int sessionsCountValue(String key) {
+	private int sessionsCountValue(final String key) {
 		try {
-			View view = new View("statistic/count_sessions");
+			final View view = new View("statistic/count_sessions");
 			view.setGroup(true);
 
-			ViewResults results = this.getDatabase().view(view);
+			final ViewResults results = getDatabase().view(view);
 			if (isEmptyResults(results)) {
 				return 0;
 			}
 
 			int result = 0;
-			JSONArray rows = results.getJSONArray("rows");
+			final JSONArray rows = results.getJSONArray("rows");
 
 			for (int i = 0; i < rows.size(); i++) {
-				JSONObject row = rows.getJSONObject(i);
+				final JSONObject row = rows.getJSONObject(i);
 				if (
 						row.getString("key").equals(key)
 						) {
@@ -821,48 +817,49 @@ public class CouchDBDao implements IDatabaseDao {
 				}
 			}
 			return result;
-		} catch (Exception e) {
+		} catch (final Exception e) {
 			LOGGER.error("Error while retrieving session count", e);
 		}
 		return 0;
 	}
 
 	@Override
-	public InterposedQuestion getInterposedQuestion(String questionId) {
+	public InterposedQuestion getInterposedQuestion(final String questionId) {
 		try {
-			Document document = this.getDatabase().getDocument(questionId);
-			InterposedQuestion question = (InterposedQuestion) JSONObject.toBean(document.getJSONObject(),
+			final Document document = getDatabase().getDocument(questionId);
+			final InterposedQuestion question = (InterposedQuestion) JSONObject.toBean(document.getJSONObject(),
 					InterposedQuestion.class);
 			question.setSessionId(getSessionKeyword(question.getSessionId()));
 			return question;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not load interposed question {}", questionId);
 		}
 		return null;
 	}
 
 	@Override
-	public void markInterposedQuestionAsRead(InterposedQuestion question) {
+	public void markInterposedQuestionAsRead(final InterposedQuestion question) {
 		try {
 			question.setRead(true);
-			Document document = this.getDatabase().getDocument(question.get_id());
+			final Document document = getDatabase().getDocument(question.get_id());
 			document.put("read", question.isRead());
-			this.getDatabase().saveDocument(document);
-		} catch (IOException e) {
+			getDatabase().saveDocument(document);
+		} catch (final IOException e) {
 			LOGGER.error("Coulg not mark interposed question as read {}", question.get_id());
 		}
 	}
 
 	@Override
-	public List<Session> getMyVisitedSessions(User user) {
-		NovaView view = new NovaView("logged_in/visited_sessions_by_user");
+	public List<Session> getMyVisitedSessions(final User user) {
+		final NovaView view = new NovaView("logged_in/visited_sessions_by_user");
 		view.setKey(user.getUsername());
-		ViewResults sessions = this.getDatabase().view(view);
-		List<Session> allSessions = new ArrayList<Session>();
-		for (Document d : sessions.getResults()) {
+		final ViewResults sessions = getDatabase().view(view);
+		final List<Session> allSessions = new ArrayList<Session>();
+		for (final Document d : sessions.getResults()) {
 			// Not all users have visited sessions
 			if (d.getJSONObject().optJSONArray("value") != null) {
 				@SuppressWarnings("unchecked")
+				final
 				Collection<Session> visitedSessions =  JSONArray.toCollection(
 						d.getJSONObject().getJSONArray("value"),
 						Session.class
@@ -871,9 +868,9 @@ public class CouchDBDao implements IDatabaseDao {
 			}
 		}
 		// Do these sessions still exist?
-		List<Session> result = new ArrayList<Session>();
-		for (Session s : allSessions) {
-			Session session = this.getSessionFromKeyword(s.getKeyword());
+		final List<Session> result = new ArrayList<Session>();
+		for (final Session s : allSessions) {
+			final Session session = getSessionFromKeyword(s.getKeyword());
 			if (session != null) {
 				result.add(session);
 			}
@@ -882,9 +879,9 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public Answer saveAnswer(Answer answer, User user) {
+	public Answer saveAnswer(final Answer answer, final User user) {
 		try {
-			Document a = new Document();
+			final Document a = new Document();
 			a.put("type", "skill_question_answer");
 			a.put("sessionId", answer.getSessionId());
 			a.put("questionId", answer.getQuestionId());
@@ -896,62 +893,62 @@ public class CouchDBDao implements IDatabaseDao {
 			a.put("user", user.getUsername());
 			a.put("piRound", answer.getPiRound());
 			a.put("abstention", answer.isAbstention());
-			this.database.saveDocument(a);
+			database.saveDocument(a);
 			answer.set_id(a.getId());
 			answer.set_rev(a.getRev());
 			return answer;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not save answer {}", answer);
 		}
 		return null;
 	}
 
 	@Override
-	public Answer updateAnswer(Answer answer) {
+	public Answer updateAnswer(final Answer answer) {
 		try {
-			Document a = this.database.getDocument(answer.get_id());
+			final Document a = database.getDocument(answer.get_id());
 			a.put("answerSubject", answer.getAnswerSubject());
 			a.put("answerText", answer.getAnswerText());
 			a.put("timestamp", answer.getTimestamp());
 			a.put("abstention", answer.isAbstention());
 			a.put("questionValue", answer.getQuestionValue());
-			this.database.saveDocument(a);
+			database.saveDocument(a);
 			answer.set_rev(a.getRev());
 			return answer;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not save answer {}", answer);
 		}
 		return null;
 	}
 
 	@Override
-	public void deleteAnswer(String answerId) {
+	public void deleteAnswer(final String answerId) {
 		try {
-			this.database.deleteDocument(this.database.getDocument(answerId));
-		} catch (IOException e) {
+			database.deleteDocument(database.getDocument(answerId));
+		} catch (final IOException e) {
 			LOGGER.error("Could not delete answer {} because of {}", answerId, e.getMessage());
 		}
 	}
 
 	@Override
-	public void deleteInterposedQuestion(InterposedQuestion question) {
+	public void deleteInterposedQuestion(final InterposedQuestion question) {
 		try {
-			this.deleteDocument(question.get_id());
-		} catch (IOException e) {
+			deleteDocument(question.get_id());
+		} catch (final IOException e) {
 			LOGGER.error("Could not delete interposed question {} because of {}", question.get_id(), e.getMessage());
 		}
 	}
 
 	@Override
-	public List<Session> getCourseSessions(List<Course> courses) {
-		ExtendedView view = new ExtendedView("logged_in/available_moodlesessions");
+	public List<Session> getCourseSessions(final List<Course> courses) {
+		final ExtendedView view = new ExtendedView("logged_in/available_moodlesessions");
 		view.setCourseIdKeys(courses);
 
-		ViewResults sessions = this.getDatabase().view(view);
+		final ViewResults sessions = getDatabase().view(view);
 
-		List<Session> result = new ArrayList<Session>();
-		for (Document d : sessions.getResults()) {
-			Session session = (Session) JSONObject.toBean(
+		final List<Session> result = new ArrayList<Session>();
+		for (final Document d : sessions.getResults()) {
+			final Session session = (Session) JSONObject.toBean(
 					d.getJSONObject().getJSONObject("value"),
 					Session.class
 					);
@@ -961,15 +958,15 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public final List<String> getActiveUsers(int timeDifference) {
-		long inactiveBeforeTimestamp = new Date().getTime() - timeDifference * 1000;
+	public final List<String> getActiveUsers(final int timeDifference) {
+		final long inactiveBeforeTimestamp = new Date().getTime() - timeDifference * 1000;
 
-		NovaView view = new NovaView("logged_in/by_and_only_timestamp_and_username");
+		final NovaView view = new NovaView("logged_in/by_and_only_timestamp_and_username");
 		view.setStartKeyArray(String.valueOf(inactiveBeforeTimestamp));
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 
-		List<String> result = new ArrayList<String>();
-		for (Document d : results.getResults()) {
+		final List<String> result = new ArrayList<String>();
+		for (final Document d : results.getResults()) {
 			result.add(d.getJSONObject().getJSONArray("key").getString(1));
 		}
 		return result;
@@ -979,21 +976,21 @@ public class CouchDBDao implements IDatabaseDao {
 
 		private String keys;
 
-		public ExtendedView(String fullname) {
+		public ExtendedView(final String fullname) {
 			super(fullname);
 		}
 
-		public void setKeys(String newKeys) {
-			this.keys = newKeys;
+		public void setKeys(final String newKeys) {
+			keys = newKeys;
 		}
 
-		public void setCourseIdKeys(List<Course> courses) {
+		public void setCourseIdKeys(final List<Course> courses) {
 			if (courses.isEmpty()) {
-				this.keys = "[]";
+				keys = "[]";
 				return;
 			}
 
-			StringBuilder sb = new StringBuilder();
+			final StringBuilder sb = new StringBuilder();
 			sb.append("[");
 			for (int i = 0; i < courses.size() - 1; i++) {
 				sb.append("\"" + courses.get(i).getId() + "\",");
@@ -1001,24 +998,24 @@ public class CouchDBDao implements IDatabaseDao {
 			sb.append("\"" + courses.get(courses.size() - 1).getId() + "\"");
 			sb.append("]");
 			try {
-				this.setKeys(URLEncoder.encode(sb.toString(), "UTF-8"));
-			} catch (UnsupportedEncodingException e) {
+				setKeys(URLEncoder.encode(sb.toString(), "UTF-8"));
+			} catch (final UnsupportedEncodingException e) {
 				LOGGER.error("Error while encoding course ID keys", e);
 			}
 		}
 
 		@Override
 		public String getQueryString() {
-			StringBuilder query = new StringBuilder();
+			final StringBuilder query = new StringBuilder();
 			if (super.getQueryString() != null) {
 				query.append(super.getQueryString());
 			}
-			if (this.keys != null) {
+			if (keys != null) {
 				if (query.toString().isEmpty()) {
 					query.append("&");
 				}
 
-				query.append("keys=" + this.keys);
+				query.append("keys=" + keys);
 			}
 
 			if (query.toString().isEmpty()) {
@@ -1029,31 +1026,31 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public Session lockSession(Session session, Boolean lock) {
+	public Session lockSession(final Session session, final Boolean lock) {
 		try {
-			Document s = this.database.getDocument(session.get_id());
+			final Document s = database.getDocument(session.get_id());
 			s.put("active", lock);
-			this.database.saveDocument(s);
+			database.saveDocument(s);
 			session.set_rev(s.getRev());
 			return session;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not lock session {}", session);
 		}
 		return null;
 	}
 
 	@Override
-	public Session updateSession(Session session) {
+	public Session updateSession(final Session session) {
 		try {
-			Document s = this.database.getDocument(session.get_id());
+			final Document s = database.getDocument(session.get_id());
 			s.put("name", session.getName());
 			s.put("shortName", session.getShortName());
 			s.put("active", session.isActive());
-			this.database.saveDocument(s);
+			database.saveDocument(s);
 			session.set_rev(s.getRev());
 
 			return session;
-		} catch (IOException e) {
+		} catch (final IOException e) {
 			LOGGER.error("Could not lock session {}", session);
 		}
 
@@ -1061,16 +1058,16 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public void deleteSession(Session session) {
+	public void deleteSession(final Session session) {
 		try {
-			this.deleteDocument(session.get_id());
-		} catch (IOException e) {
+			deleteDocument(session.get_id());
+		} catch (final IOException e) {
 			LOGGER.error("Could not delete session {}", session);
 		}
 	}
 
 	@Override
-	public List<Question> getLectureQuestions(User user, Session session) {
+	public List<Question> getLectureQuestions(final User user, final Session session) {
 		String viewName;
 		if (session.isCreator(user)) {
 			viewName = "skill_question/lecture_question_by_session";
@@ -1085,7 +1082,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public List<Question> getFlashcards(User user, Session session) {
+	public List<Question> getFlashcards(final User user, final Session session) {
 		String viewName;
 		if (session.isCreator(user)) {
 			viewName = "skill_question/flashcard_by_session";
@@ -1100,7 +1097,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public List<Question> getPreparationQuestions(User user, Session session) {
+	public List<Question> getPreparationQuestions(final User user, final Session session) {
 		String viewName;
 		if (session.isCreator(user)) {
 			viewName = "skill_question/preparation_question_by_session";
@@ -1115,24 +1112,25 @@ public class CouchDBDao implements IDatabaseDao {
 
 	}
 
-	private List<Question> getQuestions(NovaView view, Session session) {
+	private List<Question> getQuestions(final NovaView view, final Session session) {
 		view.setStartKeyArray(session.get_id());
 		view.setEndKeyArray(session.get_id(), "{}");
-		ViewResults questions = this.getDatabase().view(view);
+		final ViewResults questions = getDatabase().view(view);
 		if (questions == null || questions.isEmpty()) {
 			return null;
 		}
-		List<Question> result = new ArrayList<Question>();
+		final List<Question> result = new ArrayList<Question>();
 
-		MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
-		Morpher dynaMorpher = new BeanMorpher(PossibleAnswer.class, morpherRegistry);
+		final MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
+		final Morpher dynaMorpher = new BeanMorpher(PossibleAnswer.class, morpherRegistry);
 		morpherRegistry.registerMorpher(dynaMorpher);
-		for (Document document : questions.getResults()) {
-			Question question = (Question) JSONObject.toBean(
+		for (final Document document : questions.getResults()) {
+			final Question question = (Question) JSONObject.toBean(
 					document.getJSONObject().getJSONObject("value"),
 					Question.class
 					);
 			@SuppressWarnings("unchecked")
+			final
 			Collection<PossibleAnswer> answers = JSONArray.toCollection(
 					document.getJSONObject().getJSONObject("value").getJSONArray("possibleAnswers"),
 					PossibleAnswer.class
@@ -1149,23 +1147,23 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getLectureQuestionCount(Session session) {
+	public int getLectureQuestionCount(final Session session) {
 		return getQuestionCount(new NovaView("skill_question/lecture_question_count_by_session"), session);
 	}
 
 	@Override
-	public int getFlashcardCount(Session session) {
+	public int getFlashcardCount(final Session session) {
 		return getQuestionCount(new NovaView("skill_question/flashcard_count_by_session"), session);
 	}
 
 	@Override
-	public int getPreparationQuestionCount(Session session) {
+	public int getPreparationQuestionCount(final Session session) {
 		return getQuestionCount(new NovaView("skill_question/preparation_question_count_by_session"), session);
 	}
 
-	private int getQuestionCount(NovaView view, Session session) {
+	private int getQuestionCount(final NovaView view, final Session session) {
 		view.setKey(session.get_id());
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getJSONArray("rows").optJSONObject(0) == null) {
 			return 0;
 		}
@@ -1173,19 +1171,19 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int countLectureQuestionAnswers(Session session) {
+	public int countLectureQuestionAnswers(final Session session) {
 		return countQuestionVariantAnswers(session, "lecture");
 	}
 
 	@Override
-	public int countPreparationQuestionAnswers(Session session) {
+	public int countPreparationQuestionAnswers(final Session session) {
 		return countQuestionVariantAnswers(session, "preparation");
 	}
 
-	private int countQuestionVariantAnswers(Session session, String variant) {
-		NovaView view = new NovaView("skill_question/count_answers_by_session_and_question_variant");
+	private int countQuestionVariantAnswers(final Session session, final String variant) {
+		final NovaView view = new NovaView("skill_question/count_answers_by_session_and_question_variant");
 		view.setKey(session.get_id(), variant);
-		ViewResults results = this.getDatabase().view(view);
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().size() == 0) {
 			return 0;
 		}
@@ -1193,31 +1191,31 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public void deleteAllLectureQuestionsWithAnswers(Session session) {
-		NovaView view = new NovaView("skill_question/lecture_question_by_session");
+	public void deleteAllLectureQuestionsWithAnswers(final Session session) {
+		final NovaView view = new NovaView("skill_question/lecture_question_by_session");
 		deleteAllQuestionDocumentsWithAnswers(session, view);
 	}
 
 	@Override
-	public void deleteAllFlashcardsWithAnswers(Session session) {
-		NovaView view = new NovaView("skill_question/flashcard_by_session");
+	public void deleteAllFlashcardsWithAnswers(final Session session) {
+		final NovaView view = new NovaView("skill_question/flashcard_by_session");
 		deleteAllQuestionDocumentsWithAnswers(session, view);
 	}
 
 	@Override
-	public void deleteAllPreparationQuestionsWithAnswers(Session session) {
-		NovaView view = new NovaView("skill_question/preparation_question_by_session");
+	public void deleteAllPreparationQuestionsWithAnswers(final Session session) {
+		final NovaView view = new NovaView("skill_question/preparation_question_by_session");
 		deleteAllQuestionDocumentsWithAnswers(session, view);
 	}
 
 	@Override
-	public List<String> getUnAnsweredLectureQuestionIds(Session session, User user) {
-		NovaView view = new NovaView("answer/variant_by_user");
+	public List<String> getUnAnsweredLectureQuestionIds(final Session session, final User user) {
+		final NovaView view = new NovaView("answer/variant_by_user");
 		view.setKey(user.getUsername(), session.get_id(), "lecture");
-		return collectUnansweredQuestionIds(session, user, this.getLectureQuestionIds(session, user), view);
+		return collectUnansweredQuestionIds(session, user, getLectureQuestionIds(session, user), view);
 	}
 
-	private List<String> getLectureQuestionIds(Session session, User user) {
+	private List<String> getLectureQuestionIds(final Session session, final User user) {
 		NovaView view;
 		if (user.getType().equals("thm")) {
 			view = new NovaView("skill_question/lecture_question_by_session_for_thm");
@@ -1230,13 +1228,13 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public List<String> getUnAnsweredPreparationQuestionIds(Session session, User user) {
-		NovaView view = new NovaView("answer/variant_by_user");
+	public List<String> getUnAnsweredPreparationQuestionIds(final Session session, final User user) {
+		final NovaView view = new NovaView("answer/variant_by_user");
 		view.setKey(user.getUsername(), session.get_id(), "preparation");
-		return collectUnansweredQuestionIds(session, user, this.getPreparationQuestionIds(session, user), view);
+		return collectUnansweredQuestionIds(session, user, getPreparationQuestionIds(session, user), view);
 	}
 
-	private List<String> getPreparationQuestionIds(Session session, User user) {
+	private List<String> getPreparationQuestionIds(final Session session, final User user) {
 		NovaView view;
 		if (user.getType().equals("thm")) {
 			view = new NovaView("skill_question/preparation_question_by_session_for_thm");
@@ -1248,16 +1246,16 @@ public class CouchDBDao implements IDatabaseDao {
 		return collectQuestionIds(view);
 	}
 
-	private List<String> collectUnansweredQuestionIds(Session session, User user, List<String> questions, NovaView view) {
-		ViewResults answeredQuestions = this.getDatabase().view(view);
+	private List<String> collectUnansweredQuestionIds(final Session session, final User user, final List<String> questions, final NovaView view) {
+		final ViewResults answeredQuestions = getDatabase().view(view);
 
-		List<String> answered = new ArrayList<String>();
-		for (Document d : answeredQuestions.getResults()) {
+		final List<String> answered = new ArrayList<String>();
+		for (final Document d : answeredQuestions.getResults()) {
 			answered.add(d.getString("value"));
 		}
 
-		List<String> unanswered = new ArrayList<String>();
-		for (String questionId : questions) {
+		final List<String> unanswered = new ArrayList<String>();
+		for (final String questionId : questions) {
 			if (!answered.contains(questionId)) {
 				unanswered.add(questionId);
 			}
@@ -1265,67 +1263,67 @@ public class CouchDBDao implements IDatabaseDao {
 		return unanswered;
 	}
 
-	private List<String> collectQuestionIds(NovaView view) {
-		ViewResults results = this.getDatabase().view(view);
+	private List<String> collectQuestionIds(final NovaView view) {
+		final ViewResults results = getDatabase().view(view);
 		if (results.getResults().size() == 0) {
 			return new ArrayList<String>();
 		}
-		List<String> ids = new ArrayList<String>();
-		for (Document d : results.getResults()) {
+		final List<String> ids = new ArrayList<String>();
+		for (final Document d : results.getResults()) {
 			ids.add(d.getId());
 		}
 		return ids;
 	}
 
 	@Override
-	public void deleteAllInterposedQuestions(Session session) {
-		NovaView view = new NovaView("interposed_question/by_session");
+	public void deleteAllInterposedQuestions(final Session session) {
+		final NovaView view = new NovaView("interposed_question/by_session");
 		view.setKey(session.get_id());
-		ViewResults questions = this.getDatabase().view(view);
+		final ViewResults questions = getDatabase().view(view);
 		if (questions == null || questions.isEmpty()) {
 			return;
 		}
-		for (Document document : questions.getResults()) {
+		for (final Document document : questions.getResults()) {
 			try {
-				this.deleteDocument(document.getId());
-			} catch (IOException e) {
+				deleteDocument(document.getId());
+			} catch (final IOException e) {
 				LOGGER.error("Could not delete all interposed questions {}", session);
 			}
 		}
 	}
 
 	@Override
-	public void publishAllQuestions(Session session, boolean publish) {
-		List<Question> questions = this.getQuestions(new NovaView("skill_question/by_session"), session);
-		for (Question q : questions) {
+	public void publishAllQuestions(final Session session, final boolean publish) {
+		final List<Question> questions = getQuestions(new NovaView("skill_question/by_session"), session);
+		for (final Question q : questions) {
 			q.setActive(publish);
 		}
-		List<Document> documents = new ArrayList<Document>();
-		for (Question q : questions) {
-			Document d = toQuestionDocument(session, q);
+		final List<Document> documents = new ArrayList<Document>();
+		for (final Question q : questions) {
+			final Document d = toQuestionDocument(session, q);
 			d.setId(q.get_id());
 			d.setRev(q.get_rev());
 			documents.add(d);
 		}
 		try {
-			this.database.bulkSaveDocuments(documents.toArray(new Document[documents.size()]));
-		} catch (IOException e) {
+			database.bulkSaveDocuments(documents.toArray(new Document[documents.size()]));
+		} catch (final IOException e) {
 			LOGGER.error("Could not bulk publish all questions: {}", e.getMessage());
 		}
 	}
 
 	@Override
-	public void deleteAllQuestionsAnswers(Session session) {
-		List<Question> questions = this.getQuestions(new NovaView("skill_question/by_session"), session);
-		for (Question q : questions) {
-			this.deleteAnswers(q);
+	public void deleteAllQuestionsAnswers(final Session session) {
+		final List<Question> questions = getQuestions(new NovaView("skill_question/by_session"), session);
+		for (final Question q : questions) {
+			deleteAnswers(q);
 		}
 	}
 
 	@Override
-	public int getLearningProgress(Session session) {
-		NovaView courseView = new NovaView("learning_progress/course_value");
-		NovaView maximumView = new NovaView("learning_progress/maximum_value");
+	public int getLearningProgress(final Session session) {
+		final NovaView courseView = new NovaView("learning_progress/course_value");
+		final NovaView maximumView = new NovaView("learning_progress/maximum_value");
 		courseView.setKey(session.get_id());
 		maximumView.setKey(session.get_id());
 
@@ -1333,27 +1331,27 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getMyLearningProgress(Session session, User user) {
-		NovaView userView = new NovaView("learning_progress/user_value");
-		NovaView maximumView = new NovaView("learning_progress/maximum_value");
+	public int getMyLearningProgress(final Session session, final User user) {
+		final NovaView userView = new NovaView("learning_progress/user_value");
+		final NovaView maximumView = new NovaView("learning_progress/maximum_value");
 		userView.setKey(session.get_id(), user.getUsername());
 		maximumView.setKey(session.get_id());
 
 		return getProgressPercentage(userView, maximumView);
 	}
 
-	private int getProgressPercentage(NovaView progressView, NovaView maximumView) {
-		List<Document> progressValue = this.getDatabase().view(progressView).getResults();
-		List<Document> maximumValue = this.getDatabase().view(maximumView).getResults();
+	private int getProgressPercentage(final NovaView progressView, final NovaView maximumView) {
+		final List<Document> progressValue = getDatabase().view(progressView).getResults();
+		final List<Document> maximumValue = getDatabase().view(maximumView).getResults();
 		if (maximumValue.isEmpty()) {
 			return 0;
 		}
-		int maximum = maximumValue.get(0).getInt("value");
+		final int maximum = maximumValue.get(0).getInt("value");
 		int progress = 0;
 		if (!progressValue.isEmpty()) {
 			progress = progressValue.get(0).getInt("value");
 		}
-		int percentage = (int)((progress * 100.0f) / maximum);
+		final int percentage = (int)(progress * 100.0f / maximum);
 		return percentage < 0 ? 0 : percentage;
 	}
 }
diff --git a/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java b/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java
index fafefd1b..d76f77cf 100644
--- a/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java
+++ b/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java
@@ -53,8 +53,15 @@ public class ApplicationPermissionEvaluator implements PermissionEvaluator {
 	}
 
 	private boolean checkSessionPermission(final String username, final Serializable targetId, final Object permission) {
-		if (permission instanceof String && permission.equals("owner")) {
-			return dao.getSession(targetId.toString()).getCreator().equals(username);
+		try {
+			if (permission instanceof String && (permission.equals("owner") || permission.equals("write"))) {
+				return dao.getSession(targetId.toString()).getCreator().equals(username);
+			} else if (permission instanceof String && permission.equals("read")) {
+				return dao.getSession(targetId.toString()).isActive();
+			}
+		}
+		catch (final NullPointerException e) {
+			e.printStackTrace();
 		}
 		return false;
 	}
diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java
index 765b70df..30d96012 100644
--- a/src/main/java/de/thm/arsnova/services/SessionService.java
+++ b/src/main/java/de/thm/arsnova/services/SessionService.java
@@ -45,6 +45,24 @@ import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 @Service
 public class SessionService implements ISessionService {
 
+	public static class SessionNameComperator implements Comparator<Session>, Serializable {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public int compare(final Session session1, final Session session2) {
+			return session1.getName().compareToIgnoreCase(session2.getName());
+		}
+	}
+
+	public static class SessionShortNameComperator implements Comparator<Session>, Serializable {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public int compare(final Session session1, final Session session2) {
+			return session1.getShortName().compareToIgnoreCase(session2.getShortName());
+		}
+	}
+
 	@Autowired
 	private IDatabaseDao databaseDao;
 
@@ -58,18 +76,18 @@ public class SessionService implements ISessionService {
 	private ConnectorClient connectorClient;
 
 	public void setDatabaseDao(final IDatabaseDao newDatabaseDao) {
-		this.databaseDao = newDatabaseDao;
+		databaseDao = newDatabaseDao;
 	}
 
 	@Override
 	public final Session joinSession(final String keyword, final UUID socketId) {
 		/* Socket.IO solution */
 
-		Session session = databaseDao.getSession(keyword);
+		final Session session = databaseDao.getSession(keyword);
 		if (null == session) {
 			throw new NotFoundException();
 		}
-		User user = userService.getUser2SocketId(socketId);
+		final User user = userService.getUser2SocketId(socketId);
 
 		userService.addUserToSessionBySocketId(socketId, keyword);
 
@@ -79,7 +97,7 @@ public class SessionService implements ISessionService {
 		databaseDao.registerAsOnlineUser(user, session);
 
 		if (connectorClient != null && session.isCourseSession()) {
-			String courseid = session.getCourseId();
+			final String courseid = session.getCourseId();
 			if (!connectorClient.getMembership(user.getUsername(), courseid).isMember()) {
 				throw new ForbiddenException();
 			}
@@ -93,8 +111,8 @@ public class SessionService implements ISessionService {
 	public final Session joinSession(final String keyword) {
 		/* HTTP polling solution (legacy) */
 
-		User user = userService.getCurrentUser();
-		Session session = databaseDao.getSessionFromKeyword(keyword);
+		final User user = userService.getCurrentUser();
+		final Session session = databaseDao.getSessionFromKeyword(keyword);
 		if (session == null) {
 			throw new NotFoundException();
 		}
@@ -111,7 +129,7 @@ public class SessionService implements ISessionService {
 		socketIoServer.reportFeedbackForUserInSession(session, userService.getCurrentUser());
 
 		if (connectorClient != null && session.isCourseSession()) {
-			String courseid = session.getCourseId();
+			final String courseid = session.getCourseId();
 			if (!connectorClient.getMembership(userService.getCurrentUser().getUsername(), courseid).isMember()) {
 				throw new ForbiddenException();
 			}
@@ -123,21 +141,21 @@ public class SessionService implements ISessionService {
 	@Override
 	@PreAuthorize("isAuthenticated()")
 	public final List<Session> getMySessions(final User user) {
-		List<Session> mySessions = databaseDao.getMySessions(user);
+		final List<Session> mySessions = databaseDao.getMySessions(user);
 		if (connectorClient == null) {
 			return mySessions;
 		}
 
-		List<Session> courseSessions = databaseDao.getCourseSessions(
+		final List<Session> courseSessions = databaseDao.getCourseSessions(
 				connectorClient.getCourses(user.getUsername()).getCourse()
 				);
 
-		Map<String, Session> allAvailableSessions = new HashMap<String, Session>();
+		final Map<String, Session> allAvailableSessions = new HashMap<String, Session>();
 
-		for (Session session : mySessions) {
+		for (final Session session : mySessions) {
 			allAvailableSessions.put(session.get_id(), session);
 		}
-		for (Session session : courseSessions) {
+		for (final Session session : courseSessions) {
 			allAvailableSessions.put(session.get_id(), session);
 		}
 		return new ArrayList<Session>(allAvailableSessions.values());
@@ -171,10 +189,10 @@ public class SessionService implements ISessionService {
 	public final String generateKeyword() {
 		final int low = 10000000;
 		final int high = 100000000;
-		String keyword = String
+		final String keyword = String
 				.valueOf((int) (Math.random() * (high - low) + low));
 
-		if (this.sessionKeyAvailable(keyword)) {
+		if (sessionKeyAvailable(keyword)) {
 			return keyword;
 		}
 		return generateKeyword();
@@ -185,7 +203,7 @@ public class SessionService implements ISessionService {
 	public final LoggedIn registerAsOnlineUser(final User user, final String sessionkey) {
 		/* HTTP polling solution (legacy) */
 
-		Session session = this.joinSession(sessionkey);
+		final Session session = this.joinSession(sessionkey);
 		if (session == null) {
 			return null;
 		}
@@ -196,27 +214,9 @@ public class SessionService implements ISessionService {
 		return databaseDao.registerAsOnlineUser(user, session);
 	}
 
-	public static class SessionNameComperator implements Comparator<Session>, Serializable {
-		private static final long serialVersionUID = 1L;
-
-		@Override
-		public int compare(Session session1, Session session2) {
-			return session1.getName().compareToIgnoreCase(session2.getName());
-		}
-	}
-
-	public static class SessionShortNameComperator implements Comparator<Session>, Serializable {
-		private static final long serialVersionUID = 1L;
-
-		@Override
-		public int compare(Session session1, Session session2) {
-			return session1.getShortName().compareToIgnoreCase(session2.getShortName());
-		}
-	}
-
 	@Override
-	public int countSessions(List<Course> courses) {
-		List<Session> sessions = databaseDao.getCourseSessions(courses);
+	public int countSessions(final List<Course> courses) {
+		final List<Session> sessions = databaseDao.getCourseSessions(courses);
 		if (sessions == null) {
 			return 0;
 		}
@@ -224,9 +224,9 @@ public class SessionService implements ISessionService {
 	}
 
 	@Override
-	public Session setActive(String sessionkey, Boolean lock) {
-		Session session = databaseDao.getSessionFromKeyword(sessionkey);
-		User user = userService.getCurrentUser();
+	public Session setActive(final String sessionkey, final Boolean lock) {
+		final Session session = databaseDao.getSessionFromKeyword(sessionkey);
+		final User user = userService.getCurrentUser();
 		if (!session.isCreator(user)) {
 			throw new ForbiddenException();
 		}
@@ -235,18 +235,15 @@ public class SessionService implements ISessionService {
 
 	@Override
 	@PreAuthorize("isAuthenticated() and hasPermission(#session, 'owner')")
-	public Session updateSession(String sessionkey, Session session) {
+	public Session updateSession(final String sessionkey, final Session session) {
 		return databaseDao.updateSession(session);
 	}
 
 	@Override
-	@PreAuthorize("isAuthenticated()")
-	public void deleteSession(String sessionkey, User user) {
-		Session session = databaseDao.getSession(sessionkey);
-		if (!session.isCreator(user)) {
-			throw new ForbiddenException();
-		}
-		for (Question q : databaseDao.getSkillQuestions(user, session)) {
+	@PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')")
+	public void deleteSession(final String sessionkey, final User user) {
+		final Session session = databaseDao.getSession(sessionkey);
+		for (final Question q : databaseDao.getSkillQuestions(user, session)) {
 			databaseDao.deleteQuestionWithAnswers(q);
 		}
 		databaseDao.deleteSession(session);
@@ -254,16 +251,16 @@ public class SessionService implements ISessionService {
 
 	@Override
 	@PreAuthorize("isAuthenticated()")
-	public int getLearningProgress(String sessionkey) {
-		Session session = databaseDao.getSession(sessionkey);
+	public int getLearningProgress(final String sessionkey) {
+		final Session session = databaseDao.getSession(sessionkey);
 		return databaseDao.getLearningProgress(session);
 	}
 
 	@Override
 	@PreAuthorize("isAuthenticated()")
-	public int getMyLearningProgress(String sessionkey) {
-		Session session = databaseDao.getSession(sessionkey);
-		User user = userService.getCurrentUser();
+	public int getMyLearningProgress(final String sessionkey) {
+		final Session session = databaseDao.getSession(sessionkey);
+		final User user = userService.getCurrentUser();
 		return databaseDao.getMyLearningProgress(session, user);
 	}
 }
diff --git a/src/test/java/de/thm/arsnova/services/SessionServiceTest.java b/src/test/java/de/thm/arsnova/services/SessionServiceTest.java
index 6b6ecd31..eb74960a 100644
--- a/src/test/java/de/thm/arsnova/services/SessionServiceTest.java
+++ b/src/test/java/de/thm/arsnova/services/SessionServiceTest.java
@@ -167,6 +167,7 @@ public class SessionServiceTest {
 			setAuthenticated(true, "ptsr00");
 
 			final Session session = new Session();
+			session.setKeyword("12345678");
 			session.setCreator(userService.getCurrentUser().getUsername());
 			final Question q1 = new Question();
 			final Question q2 = new Question();
@@ -186,6 +187,18 @@ public class SessionServiceTest {
 		}
 	}
 
+	@Test(expected = AuthenticationCredentialsNotFoundException.class)
+	public void testShouldNotDeleteSessionIfUnauthorized() {
+		setAuthenticated(false, "nobody");
+		sessionService.deleteSession("12345678", userService.getCurrentUser());
+	}
+
+	@Test(expected = ForbiddenException.class)
+	public void testShouldNotDeleteSessionIfNotOwner() {
+		setAuthenticated(true, "anybody");
+		sessionService.deleteSession("12345678", userService.getCurrentUser());
+	}
+
 	@Test
 	public void testShouldCompareSessionByName() {
 		final Session sessionA = new Session();
-- 
GitLab