From 30f8c467bf0e338154ef8fc2fac53f680b1356af Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer <paul-christian.volkmer@mni.thm.de> Date: Wed, 21 May 2014 07:02:19 +0200 Subject: [PATCH] Make use of spring security to secure service methods --- .../thm/arsnova/annotation/Authenticated.java | 12 --- .../thm/arsnova/annotation/package-info.java | 1 - .../thm/arsnova/aop/AuthorizationAdviser.java | 48 --------- .../controller/AbstractController.java | 18 +++- .../security/SessionPermissionEvaluator.java | 18 +++- .../de/thm/arsnova/services/FoodService.java | 4 +- .../thm/arsnova/services/QuestionService.java | 102 +++++++++--------- .../thm/arsnova/services/SessionService.java | 16 +-- .../webapp/WEB-INF/spring/spring-main.xml | 4 - .../controller/SessionControllerTest.java | 40 ++++--- .../arsnova/services/QuestionServiceTest.java | 37 +++++-- .../arsnova/services/SessionServiceTest.java | 33 ++++-- src/test/resources/test-config.xml | 16 ++- 13 files changed, 181 insertions(+), 168 deletions(-) delete mode 100644 src/main/java/de/thm/arsnova/annotation/Authenticated.java delete mode 100644 src/main/java/de/thm/arsnova/annotation/package-info.java delete mode 100644 src/main/java/de/thm/arsnova/aop/AuthorizationAdviser.java diff --git a/src/main/java/de/thm/arsnova/annotation/Authenticated.java b/src/main/java/de/thm/arsnova/annotation/Authenticated.java deleted file mode 100644 index b619ea11d..000000000 --- a/src/main/java/de/thm/arsnova/annotation/Authenticated.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.thm.arsnova.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface Authenticated { - -} diff --git a/src/main/java/de/thm/arsnova/annotation/package-info.java b/src/main/java/de/thm/arsnova/annotation/package-info.java deleted file mode 100644 index 5a442d364..000000000 --- a/src/main/java/de/thm/arsnova/annotation/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package de.thm.arsnova.annotation; diff --git a/src/main/java/de/thm/arsnova/aop/AuthorizationAdviser.java b/src/main/java/de/thm/arsnova/aop/AuthorizationAdviser.java deleted file mode 100644 index 4e0de0dfc..000000000 --- a/src/main/java/de/thm/arsnova/aop/AuthorizationAdviser.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.thm.arsnova.aop; - -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; - -import de.thm.arsnova.annotation.Authenticated; -import de.thm.arsnova.entities.User; -import de.thm.arsnova.exceptions.UnauthorizedException; -import de.thm.arsnova.services.IUserService; - -@Aspect -public class AuthorizationAdviser { - - private IUserService userService; - - public final void setUserService(final IUserService uService) { - userService = uService; - } - - /** - * This method checks if the user has a valid authorization from security - * context - * - * @param authenticated - * @param object - */ - @Before("execution(public * de.thm.arsnova.services.*.*(..)) && @annotation(authenticated) && this(object)") - public final void checkAuthorization(final Authenticated authenticated, final Object object) { - User u = userService.getCurrentUser(); - if (u == null) { - throw new UnauthorizedException(); - } - if (u.getUsername().equals("anonymous")) { - throw new UnauthorizedException(); - } - } - - /** - * This method checks if the user is enlisted in current ARSnova session - * - * @param authenticated - * @param object - */ - @Before("execution(public * de.thm.arsnova.services.*.*(..)) && @annotation(authenticated) && this(object)") - public final void checkSessionMembership(final Authenticated authenticated, final Object object) { - /// TODO Implement check based on session membership lists - } -} diff --git a/src/main/java/de/thm/arsnova/controller/AbstractController.java b/src/main/java/de/thm/arsnova/controller/AbstractController.java index 253528c4a..a0dc60afc 100644 --- a/src/main/java/de/thm/arsnova/controller/AbstractController.java +++ b/src/main/java/de/thm/arsnova/controller/AbstractController.java @@ -3,6 +3,8 @@ package de.thm.arsnova.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @@ -19,14 +21,24 @@ public class AbstractController { public void handleNotFoundException(final Exception e, final HttpServletRequest request) { } + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ExceptionHandler(UnauthorizedException.class) + public void handleUnauthorizedException(final Exception e, final HttpServletRequest request) { + } + + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ExceptionHandler(AuthenticationCredentialsNotFoundException.class) + public void handleAuthenticationCredentialsNotFoundException(final Exception e, final HttpServletRequest request) { + } + @ResponseStatus(HttpStatus.FORBIDDEN) @ExceptionHandler(ForbiddenException.class) public void handleForbiddenException(final Exception e, final HttpServletRequest request) { } - @ResponseStatus(HttpStatus.UNAUTHORIZED) - @ExceptionHandler(UnauthorizedException.class) - public void handleUnauthorizedException(final Exception e, final HttpServletRequest request) { + @ResponseStatus(HttpStatus.FORBIDDEN) + @ExceptionHandler(AccessDeniedException.class) + public void handleAccessDeniedException(final Exception e, final HttpServletRequest request) { } @ResponseStatus(HttpStatus.NO_CONTENT) diff --git a/src/main/java/de/thm/arsnova/security/SessionPermissionEvaluator.java b/src/main/java/de/thm/arsnova/security/SessionPermissionEvaluator.java index ba910180a..4a3bef2e0 100644 --- a/src/main/java/de/thm/arsnova/security/SessionPermissionEvaluator.java +++ b/src/main/java/de/thm/arsnova/security/SessionPermissionEvaluator.java @@ -2,14 +2,19 @@ package de.thm.arsnova.security; import java.io.Serializable; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; +import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.exceptions.UnauthorizedException; public class SessionPermissionEvaluator implements PermissionEvaluator { + @Autowired + IDatabaseDao dao; + @Override public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { UserDetails user = getUserDetails(authentication); @@ -19,12 +24,23 @@ public class SessionPermissionEvaluator implements PermissionEvaluator { @Override public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { UserDetails user = getUserDetails(authentication); + + if ("session".equals(targetType)) { + return checkSessionPermission(user, targetId, permission); + } + return false; + } + + private boolean checkSessionPermission(UserDetails user, Serializable targetId, Object permission) { + if (permission instanceof String && permission.equals("owner")) { + return dao.getSession(targetId.toString()).getCreator().equals(user.getUsername()); + } return false; } private UserDetails getUserDetails(Authentication authentication) throws UnauthorizedException { - if (authentication.getPrincipal() instanceof String) { + if (authentication.getPrincipal() == null || authentication.getPrincipal() instanceof String) { throw new UnauthorizedException(); } diff --git a/src/main/java/de/thm/arsnova/services/FoodService.java b/src/main/java/de/thm/arsnova/services/FoodService.java index e43906b4d..d08824f09 100644 --- a/src/main/java/de/thm/arsnova/services/FoodService.java +++ b/src/main/java/de/thm/arsnova/services/FoodService.java @@ -22,9 +22,9 @@ package de.thm.arsnova.services; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; -import de.thm.arsnova.annotation.Authenticated; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.FoodVote; @@ -39,7 +39,7 @@ public class FoodService implements IFoodService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void vote(String menu) { this.databaseDao.vote(menu); diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java index f91da75e9..b47fc1d47 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -28,10 +28,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import de.thm.arsnova.ImageUtils; -import de.thm.arsnova.annotation.Authenticated; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.InterposedQuestion; @@ -56,10 +56,10 @@ public class QuestionService implements IQuestionService { @Autowired private ARSnovaSocketIOServer socketIoServer; - + @Value("${upload.filesize_b}") private int uploadFileSizeByte; - + public static final Logger LOGGER = LoggerFactory.getLogger(QuestionService.class); public void setDatabaseDao(IDatabaseDao databaseDao) { @@ -67,20 +67,20 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Question> getSkillQuestions(String sessionkey) { return databaseDao.getSkillQuestions(userService.getCurrentUser(), getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getSkillQuestionCount(String sessionkey) { Session session = this.databaseDao.getSessionFromKeyword(sessionkey); return databaseDao.getSkillQuestionCount(session); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Question saveQuestion(Question question) { Session session = this.databaseDao.getSessionFromKeyword(question.getSessionKeyword()); question.setSessionId(session.get_id()); @@ -96,7 +96,7 @@ public class QuestionService implements IQuestionService { } else if (question.getPiRound() < 1 || question.getPiRound() > 2) { question.setPiRound(1); } - + // convert imageurl to base64 if neccessary if ("grid".equals(question.getQuestionType())) { org.slf4j.Logger logger = LoggerFactory.getLogger(QuestionService.class); @@ -107,7 +107,7 @@ public class QuestionService implements IQuestionService { } question.setImage(base64ImageString); } - + // base64 adds offset to filesize, formular taken from: http://en.wikipedia.org/wiki/Base64#MIME int fileSize = (int)((question.getImage().length()-814)/1.37); if ( fileSize > this.uploadFileSizeByte ) { @@ -123,7 +123,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public boolean saveQuestion(InterposedQuestion question) { Session session = this.databaseDao.getSessionFromKeyword(question.getSessionId()); InterposedQuestion result = this.databaseDao.saveQuestion(session, question); @@ -138,7 +138,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Question getQuestion(String id) { Question result = databaseDao.getQuestion(id); if (result == null) { @@ -153,7 +153,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteQuestion(String questionId) { Question question = databaseDao.getQuestion(questionId); if (question == null) { @@ -169,7 +169,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteAllQuestions(String sessionKeyword) { Session session = getSessionWithAuthCheck(sessionKeyword); databaseDao.deleteAllQuestionsWithAnswers(session); @@ -185,7 +185,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteInterposedQuestion(String questionId) { InterposedQuestion question = databaseDao.getInterposedQuestion(questionId); if (question == null) { @@ -198,9 +198,9 @@ public class QuestionService implements IQuestionService { } databaseDao.deleteInterposedQuestion(question); } - + @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteAllInterposedQuestions(String sessionKeyword) { User user = userService.getCurrentUser(); Session session = databaseDao.getSessionFromKeyword(sessionKeyword); @@ -211,7 +211,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteAnswers(String questionId) { Question question = databaseDao.getQuestion(questionId); if (question == null) { @@ -227,7 +227,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<String> getUnAnsweredQuestionIds(String sessionKey) { User user = getCurrentUser(); Session session = getSession(sessionKey); @@ -243,7 +243,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Answer getMyAnswer(String questionId) { Question question = getQuestion(questionId); @@ -251,17 +251,17 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Answer> getAnswers(String questionId, int piRound) { Question question = databaseDao.getQuestion(questionId); return "freetext".equals(question.getQuestionType()) - ? getFreetextAnswers(questionId) - : databaseDao.getAnswers(questionId, piRound); + ? getFreetextAnswers(questionId) + : databaseDao.getAnswers(questionId, piRound); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Answer> getAnswers(String questionId) { Question question = getQuestion(questionId); @@ -269,15 +269,15 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getAnswerCount(String questionId) { Question question = getQuestion(questionId); - + return databaseDao.getAnswerCount(question, question.getPiRound()); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Answer> getFreetextAnswers(String questionId) { List<Answer> answers = databaseDao.getFreetextAnswers(questionId); if (answers == null) { @@ -287,7 +287,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Answer> getMyAnswers(String sessionKey) { List<Question> questions = getSkillQuestions(sessionKey); Map<String, Question> questionIdToQuestion = new HashMap<String, Question>(); @@ -312,19 +312,19 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getTotalAnswerCount(String sessionKey) { return databaseDao.getTotalAnswerCount(sessionKey); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getInterposedCount(String sessionKey) { return databaseDao.getInterposedCount(sessionKey); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public InterposedReadingCount getInterposedReadingCount(String sessionKey) { Session session = this.databaseDao.getSessionFromKeyword(sessionKey); if (session == null) { @@ -334,13 +334,13 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<InterposedQuestion> getInterposedQuestions(String sessionKey) { return databaseDao.getInterposedQuestions(sessionKey); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public InterposedQuestion readInterposedQuestion(String questionId) { InterposedQuestion question = databaseDao.getInterposedQuestion(questionId); if (question == null) { @@ -356,7 +356,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Question update(Question question) { Question oldQuestion = databaseDao.getQuestion(question.get_id()); if (null == oldQuestion) { @@ -379,7 +379,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Answer saveAnswer(Answer answer) { User user = getCurrentUser(); Question question = this.getQuestion(answer.getQuestionId()); @@ -400,7 +400,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Answer updateAnswer(Answer answer) { User user = userService.getCurrentUser(); if (user == null || !user.getUsername().equals(answer.getUser())) { @@ -415,7 +415,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteAnswer(String questionId, String answerId) { Question question = this.databaseDao.getQuestion(questionId); if (question == null) { @@ -432,23 +432,23 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Question> getLectureQuestions(String sessionkey) { return databaseDao.getLectureQuestions(userService.getCurrentUser(), getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Question> getFlashcards(String sessionkey) { return databaseDao.getFlashcards(userService.getCurrentUser(), getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<Question> getPreparationQuestions(String sessionkey) { return databaseDao.getPreparationQuestions(userService.getCurrentUser(), getSession(sessionkey)); } - + private Session getSession(String sessionkey) { Session session = this.databaseDao.getSessionFromKeyword(sessionkey); if (session == null) { @@ -458,58 +458,58 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getLectureQuestionCount(String sessionkey) { return databaseDao.getLectureQuestionCount(getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getFlashcardCount(String sessionkey) { return databaseDao.getFlashcardCount(getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getPreparationQuestionCount(String sessionkey) { return databaseDao.getPreparationQuestionCount(getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int countLectureQuestionAnswers(String sessionkey) { return databaseDao.countLectureQuestionAnswers(getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int countPreparationQuestionAnswers(String sessionkey) { return databaseDao.countPreparationQuestionAnswers(getSession(sessionkey)); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteLectureQuestions(String sessionkey) { Session session = getSessionWithAuthCheck(sessionkey); databaseDao.deleteAllLectureQuestionsWithAnswers(session); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteFlashcards(String sessionkey) { Session session = getSessionWithAuthCheck(sessionkey); databaseDao.deleteAllFlashcardsWithAnswers(session); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deletePreparationQuestions(String sessionkey) { Session session = getSessionWithAuthCheck(sessionkey); databaseDao.deleteAllPreparationQuestionsWithAnswers(session); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<String> getUnAnsweredLectureQuestionIds(String sessionkey) { User user = getCurrentUser(); Session session = getSession(sessionkey); @@ -517,7 +517,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public List<String> getUnAnsweredPreparationQuestionIds(String sessionkey) { User user = getCurrentUser(); Session session = getSession(sessionkey); @@ -525,7 +525,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void publishAll(String sessionkey, boolean publish) { User user = getCurrentUser(); Session session = getSession(sessionkey); @@ -536,7 +536,7 @@ public class QuestionService implements IQuestionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteAllQuestionsAnswers(String sessionkey) { User user = getCurrentUser(); Session session = getSession(sessionkey); diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java index 0d63d14a8..3b3c6011e 100644 --- a/src/main/java/de/thm/arsnova/services/SessionService.java +++ b/src/main/java/de/thm/arsnova/services/SessionService.java @@ -28,9 +28,9 @@ import java.util.Map; import java.util.UUID; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; -import de.thm.arsnova.annotation.Authenticated; import de.thm.arsnova.connector.client.ConnectorClient; import de.thm.arsnova.connector.model.Course; import de.thm.arsnova.dao.IDatabaseDao; @@ -89,7 +89,7 @@ public class SessionService implements ISessionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public final Session joinSession(final String keyword) { /* HTTP polling solution (legacy) */ @@ -148,7 +148,7 @@ public class SessionService implements ISessionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated() and hasPermission(#session.getKeyword(), 'session', 'owner')") public final Session saveSession(final Session session) { if (connectorClient != null && session.getCourseId() != null) { if (!connectorClient.getMembership( @@ -179,7 +179,7 @@ public class SessionService implements ISessionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public final LoggedIn registerAsOnlineUser(final User user, final String sessionkey) { /* HTTP polling solution (legacy) */ @@ -232,7 +232,7 @@ public class SessionService implements ISessionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public Session updateSession(String sessionkey, Session session) { Session s = databaseDao.getSession(sessionkey); User user = userService.getCurrentUser(); @@ -245,7 +245,7 @@ public class SessionService implements ISessionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public void deleteSession(String sessionkey, User user) { Session session = databaseDao.getSession(sessionkey); if (!session.isCreator(user)) { @@ -258,14 +258,14 @@ public class SessionService implements ISessionService { } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getLearningProgress(String sessionkey) { Session session = databaseDao.getSession(sessionkey); return databaseDao.getLearningProgress(session); } @Override - @Authenticated + @PreAuthorize("isAuthenticated()") public int getMyLearningProgress(String sessionkey) { Session session = databaseDao.getSession(sessionkey); User user = userService.getCurrentUser(); diff --git a/src/main/webapp/WEB-INF/spring/spring-main.xml b/src/main/webapp/WEB-INF/spring/spring-main.xml index 5308d696f..c23d1ddbd 100644 --- a/src/main/webapp/WEB-INF/spring/spring-main.xml +++ b/src/main/webapp/WEB-INF/spring/spring-main.xml @@ -40,10 +40,6 @@ p:portNumber="${socketio.port}" p:hostIp="${socketio.ip}" p:useSSL="${security.ssl}" p:keystore="${security.keystore}" p:storepass="${security.storepass}" /> - <bean id="authorizationAdviser" class="de.thm.arsnova.aop.AuthorizationAdviser"> - <property name="userService" ref="userService" /> - </bean> - <bean id="userSessionAspect" class="de.thm.arsnova.aop.UserSessionAspect" /> <bean id="userService" scope="singleton" class="de.thm.arsnova.services.UserService" /> diff --git a/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java b/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java index ea36714a7..b1bcb8d21 100644 --- a/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java +++ b/src/test/java/de/thm/arsnova/controller/SessionControllerTest.java @@ -4,11 +4,17 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.ArrayList; +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -45,36 +51,38 @@ public class SessionControllerTest { mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } - @Test - public void testShouldNotGetUnknownSession() throws Exception { - userService.setUserAuthenticated(true); - - mockMvc.perform(get("/session/00000000")) - .andExpect(status().isNotFound()); + private void setAuthenticated(boolean isAuthenticated) { + if (isAuthenticated) { + List<GrantedAuthority> ga = new ArrayList<GrantedAuthority>(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("ptsr00", "secret", ga); + SecurityContextHolder.getContext().setAuthentication(token); + } else { + SecurityContextHolder.createEmptyContext(); + } + userService.setUserAuthenticated(isAuthenticated); } @Test - public void testShouldNotGetSessionIfUnauthorized() throws Exception { - userService.setUserAuthenticated(false); + public void testShouldNotGetUnknownSession() throws Exception { + setAuthenticated(true); mockMvc.perform(get("/session/00000000")) - .andExpect(status().isUnauthorized()); + .andExpect(status().isNotFound()); } @Test - public void testShouldNotGetSessionIfAnonymous() throws Exception { - userService.setUserAuthenticated(false); - userService.useAnonymousUser(); + public void testShouldNotGetUnknownSessionEvenIfUnauthorized() throws Exception { + setAuthenticated(false); mockMvc.perform(get("/session/00000000")) - .andExpect(status().isUnauthorized()); + .andExpect(status().isNotFound()); } @Test - public void testShouldCreateSessionIfUnauthorized() throws Exception { - userService.setUserAuthenticated(false); + public void testShouldCreateSessionIfNotAuthorized() throws Exception { + setAuthenticated(false); mockMvc.perform(post("/session/").contentType(MediaType.APPLICATION_JSON).content("{}")) - .andExpect(status().isUnauthorized()); + .andExpect(status().isForbidden()); } } diff --git a/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java b/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java index 8113ce0bf..64e251fc3 100644 --- a/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java +++ b/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java @@ -22,17 +22,23 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.List; + import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import de.thm.arsnova.dao.StubDatabaseDao; import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.exceptions.NotFoundException; -import de.thm.arsnova.exceptions.UnauthorizedException; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { @@ -52,34 +58,47 @@ public class QuestionServiceTest { @Autowired private StubDatabaseDao databaseDao; + private void setAuthenticated(boolean isAuthenticated, String username) { + if (isAuthenticated) { + List<GrantedAuthority> ga = new ArrayList<GrantedAuthority>(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, "secret", ga); + SecurityContextHolder.getContext().setAuthentication(token); + userService.setUserAuthenticated(isAuthenticated, username); + } else { + SecurityContextHolder.setContext( + SecurityContextHolder.createEmptyContext() + ); + userService.setUserAuthenticated(isAuthenticated); + } + } + @After public final void cleanup() { databaseDao.cleanupTestData(); - userService.setUserAuthenticated(false); + setAuthenticated(false, "ptsr00"); } - @Test(expected = UnauthorizedException.class) + @Test(expected = AuthenticationCredentialsNotFoundException.class) public void testShouldNotReturnQuestionsIfNotAuthenticated() { - userService.setUserAuthenticated(false); + setAuthenticated(false, "nobody"); questionService.getSkillQuestions("12345678"); - } @Test(expected = NotFoundException.class) public void testShouldFindQuestionsForNonExistantSession() { - userService.setUserAuthenticated(true); + setAuthenticated(true, "ptsr00"); questionService.getSkillQuestions("00000000"); } @Test public void testShouldFindQuestions() { - userService.setUserAuthenticated(true); + setAuthenticated(true, "ptsr00"); assertEquals(1, questionService.getSkillQuestionCount("12345678")); } @Test public void testShouldMarkInterposedQuestionAsReadIfSessionCreator() throws Exception { - userService.setUserAuthenticated(true); + setAuthenticated(true, "ptsr00"); InterposedQuestion theQ = new InterposedQuestion(); theQ.setRead(false); theQ.set_id("the internal id"); @@ -93,7 +112,7 @@ public class QuestionServiceTest { @Test public void testShouldNotMarkInterposedQuestionAsReadIfRegularUser() throws Exception { - userService.setUserAuthenticated(true, "regular user"); + setAuthenticated(true, "regular user"); InterposedQuestion theQ = new InterposedQuestion(); theQ.setRead(false); theQ.set_id("the internal id"); diff --git a/src/test/java/de/thm/arsnova/services/SessionServiceTest.java b/src/test/java/de/thm/arsnova/services/SessionServiceTest.java index be057a0ce..12e790fd7 100644 --- a/src/test/java/de/thm/arsnova/services/SessionServiceTest.java +++ b/src/test/java/de/thm/arsnova/services/SessionServiceTest.java @@ -26,7 +26,9 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.junit.After; import org.junit.Test; @@ -34,6 +36,10 @@ import org.junit.runner.RunWith; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.util.ReflectionTestUtils; @@ -74,21 +80,32 @@ public class SessionServiceTest { assertTrue(sessionService.generateKeyword().matches("^[0-9]{8}$")); } + private void setAuthenticated(boolean isAuthenticated) { + if (isAuthenticated) { + List<GrantedAuthority> ga = new ArrayList<GrantedAuthority>(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("ptsr00", "secret", ga); + SecurityContextHolder.getContext().setAuthentication(token); + } else { + SecurityContextHolder.createEmptyContext(); + } + userService.setUserAuthenticated(isAuthenticated); + } + @Test(expected = NotFoundException.class) public void testShouldFindNonExistantSession() { - userService.setUserAuthenticated(true); + setAuthenticated(true); sessionService.joinSession("00000000"); } @Test(expected = UnauthorizedException.class) public void testShouldNotReturnSessionIfUnauthorized() { - userService.setUserAuthenticated(false); + setAuthenticated(false); sessionService.joinSession("12345678"); } - @Test(expected = UnauthorizedException.class) + @Test(expected = AccessDeniedException.class) public void testShouldNotSaveSessionIfUnauthorized() { - userService.setUserAuthenticated(false); + setAuthenticated(false); Session session = new Session(); session.setActive(true); @@ -98,14 +115,14 @@ public class SessionServiceTest { session.setShortName("TSX"); sessionService.saveSession(session); - userService.setUserAuthenticated(true); + setAuthenticated(true); assertNull(sessionService.joinSession("11111111")); } - @Test + @Test(expected = AccessDeniedException.class) public void testShouldSaveSession() { - userService.setUserAuthenticated(true); + setAuthenticated(true); Session session = new Session(); session.setActive(true); @@ -121,7 +138,7 @@ public class SessionServiceTest { public void testShouldDeleteAllSessionData() { IDatabaseDao tempDatabase = (IDatabaseDao) ReflectionTestUtils.getField(getTargetObject(sessionService), "databaseDao"); try { - userService.setUserAuthenticated(true); + setAuthenticated(true); Session session = new Session(); session.setCreator(userService.getCurrentUser().getUsername()); diff --git a/src/test/resources/test-config.xml b/src/test/resources/test-config.xml index 63c1fb147..13007cfd1 100644 --- a/src/test/resources/test-config.xml +++ b/src/test/resources/test-config.xml @@ -3,7 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:websocket="http://www.springframework.org/schema/websocket" - xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd + xmlns:security="http://www.springframework.org/schema/security" + xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> @@ -14,10 +16,6 @@ <bean id="databaseDao" class="de.thm.arsnova.dao.StubDatabaseDao"> </bean> - <bean id="authorizationAdviser" class="de.thm.arsnova.aop.AuthorizationAdviser"> - <property name="userService" ref="userService" /> - </bean> - <bean id="userService" class="de.thm.arsnova.services.StubUserService" /> <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> @@ -29,4 +27,12 @@ </map> </property> </bean> + + <security:authentication-manager> + <security:authentication-provider> + <security:user-service> + <security:user name="ptsr00" password="secret" authorities=""/> + </security:user-service> + </security:authentication-provider> + </security:authentication-manager> </beans> -- GitLab