diff --git a/src/main/java/de/thm/arsnova/controller/QuestionController.java b/src/main/java/de/thm/arsnova/controller/QuestionController.java index ac040be5a0ef36159bb5333228a9aee86b246a5c..51f97e67ba4a4482c91870339f7cb21a6462914c 100644 --- a/src/main/java/de/thm/arsnova/controller/QuestionController.java +++ b/src/main/java/de/thm/arsnova/controller/QuestionController.java @@ -35,6 +35,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import de.thm.arsnova.entities.Question; +import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.IQuestionService; import de.thm.arsnova.services.IUserService; import de.thm.arsnova.socket.ARSnovaSocketIOServer; @@ -100,4 +101,16 @@ public class QuestionController extends AbstractController { logger.info(questions.toString()); return questions; } + + @RequestMapping("/session/{sessionKey}/questionids") + @ResponseBody + public List<String> getQuestionIds(@PathVariable String sessionKey, HttpServletResponse response) { + List<String> questions = questionService.getQuestionIds(sessionKey); + if(questions == null || questions.isEmpty()) { + throw new NotFoundException(); + } + logger.info(questions.toString()); + return questions; + + } } diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index 4eb971a99b7f4709d6eee07e655f5342b9b925a7..812133c002db03bc090c71a0acada1d1a09129db 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -160,6 +160,7 @@ public class CouchDBDao implements IDatabaseDao { @Override public Session getSession(String keyword) { Session result = this.getSessionFromKeyword(keyword); + if(result == null) { throw new NotFoundException(); } @@ -252,10 +253,11 @@ public class CouchDBDao implements IDatabaseDao { View view = new View("session/by_keyword"); view.setKey(URLEncoder.encode("\"" + keyword + "\"", "UTF-8")); ViewResults results = this.getDatabase().view(view); - - if (results.getJSONArray("rows").optJSONObject(0) == null) + + if (results.getJSONArray("rows").optJSONObject(0) == null) { return null; - + } + return (Session) JSONObject.toBean( results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"), Session.class); } catch (UnsupportedEncodingException e) { @@ -566,4 +568,38 @@ public class CouchDBDao implements IDatabaseDao { return; } } + + @Override + public List<String> getQuestionIds(String sessionKey) { + User u = userService.getCurrentUser(); + View view; + if(u.getType().equals("thm")) { + view = new View("skill_question/by_session_only_id_for_thm"); + } else { + view = new View("skill_question/by_session_only_id_for_all"); + } + + String sessionId = getSessionId(sessionKey); + if(sessionId == null) { + throw new NotFoundException(); + } + + try { + view.setKey(URLEncoder.encode("\"" + sessionId + "\"", "UTF-8")); + ViewResults results = this.getDatabase().view(view); + if (results.getJSONArray("rows").optJSONObject(0) == null) { + return null; + } + + List<String> ids = new ArrayList<String>(); + for(Document d : results.getResults()) { + ids.add(d.getId()); + } + return ids; + + } catch (IOException e) { + logger.error("Could not get list of question ids of session {}", sessionKey); + } + return null; + } } diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java index ff42a9a69fad530bb623b9103babf29067fabe83..398d1b5691fa1d860baf4c7791636119f63b0892 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -44,4 +44,5 @@ public interface IDatabaseDao { public LoggedIn registerAsOnlineUser(User u, Session s); public void updateSessionOwnerActivity(Session session); + public List<String> getQuestionIds(String sessionKey); } \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/entities/User.java b/src/main/java/de/thm/arsnova/entities/User.java index 997b22078f2e7ddbce0fe1503b5ff181f309680d..75e5691f81f52565ae281316bea7972556a22e37 100644 --- a/src/main/java/de/thm/arsnova/entities/User.java +++ b/src/main/java/de/thm/arsnova/entities/User.java @@ -12,29 +12,36 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio public class User implements Serializable { private static final long serialVersionUID = 1L; private String username; + private String type; public User(Google2Profile profile) { setUsername(profile.getEmail()); + setType("google"); } public User(TwitterProfile profile) { setUsername(profile.getScreenName()); + setType("twitter"); } public User(FacebookProfile profile) { setUsername(profile.getLink()); + setType("facebook"); } public User(AttributePrincipal principal) { setUsername(principal.getName()); + setType("thm"); } public User(AnonymousAuthenticationToken token) { setUsername("anonymous"); + setType("anonymous"); } public User(UsernamePasswordAuthenticationToken token) { setUsername(token.getName()); + setType("ldap"); } public String getUsername() { @@ -45,19 +52,26 @@ public class User implements Serializable { this.username = username; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + public String toString() { - return "User, username: " + this.username; + return "User, username: " + this.username + ", type: " + this.type; } @Override public int hashCode() { - return username.hashCode(); + return username.concat(type).hashCode(); } - @Override public boolean equals(Object obj) { User other = (User) obj; - return this.username.equals(other.username); + return this.username.equals(other.username) && this.type.equals(other.type); } } diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java index 5e9d5cdb3f84d8e45a75ca74e4cf65d1c197c1f6..26b6a0ad597edce373aac6e0881b99d77693a045 100644 --- a/src/main/java/de/thm/arsnova/services/IQuestionService.java +++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java @@ -29,4 +29,5 @@ public interface IQuestionService { public Question getQuestion(String id); public List<Question> getSkillQuestions(String sessionkey); public int getSkillQuestionCount(String sessionkey); + public List<String> getQuestionIds(String sessionKey); } \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java index 2d416d98652feeef9e703b7e2dcdc35fdd643cb2..014eea5b66642b1a0199c12f0980845e18b7d0ea 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -68,4 +68,10 @@ public class QuestionService implements IQuestionService { public Question getQuestion(String id) { return databaseDao.getQuestion(id); } + + @Override + @Authenticated + public List<String> getQuestionIds(String sessionKey) { + return databaseDao.getQuestionIds(sessionKey); + } } diff --git a/src/test/java/de/thm/arsnova/controller/LoginControllerTest.java b/src/test/java/de/thm/arsnova/controller/LoginControllerTest.java index ea2c531d163c2fdd8d6d419cee2fbeecda76c61b..d0989347804bb6f7d6559af84a7cc183d468ce7c 100644 --- a/src/test/java/de/thm/arsnova/controller/LoginControllerTest.java +++ b/src/test/java/de/thm/arsnova/controller/LoginControllerTest.java @@ -113,7 +113,7 @@ public class LoginControllerTest { handlerAdapter.handle(request, response, loginController); assertNotNull(response); - assertEquals(response.getContentAsString(),"{\"username\":\"ptsr00\"}"); + assertEquals("{\"username\":\"ptsr00\",\"type\":\"ldap\"}", response.getContentAsString()); } @Test diff --git a/src/test/java/de/thm/arsnova/controller/QuestionControllerTest.java b/src/test/java/de/thm/arsnova/controller/QuestionControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..624f63c9b4a48881c81bd754c9216b5186a52866 --- /dev/null +++ b/src/test/java/de/thm/arsnova/controller/QuestionControllerTest.java @@ -0,0 +1,76 @@ +package de.thm.arsnova.controller; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import javax.inject.Inject; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.servlet.HandlerAdapter; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; + +import de.thm.arsnova.exceptions.NotFoundException; +import de.thm.arsnova.exceptions.UnauthorizedException; +import de.thm.arsnova.services.StubUserService; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "file:src/main/webapp/WEB-INF/arsnova-servlet.xml", + "file:src/main/webapp/WEB-INF/spring/spring-main.xml", + "file:src/test/resources/test-config.xml" }) +public class QuestionControllerTest { + + @Inject + private ApplicationContext applicationContext; + private MockHttpServletRequest request; + private MockHttpServletResponse response; + private HandlerAdapter handlerAdapter; + + @Autowired + private QuestionController questionController; + + @Autowired + private StubUserService userService; + + @Before + public void setUp() { + this.request = new MockHttpServletRequest(); + this.response = new MockHttpServletResponse(); + handlerAdapter = applicationContext + .getBean(AnnotationMethodHandlerAdapter.class); + } + + @Test(expected=NotFoundException.class) + public void testShouldNotGetQestionIdsForUnknownSession() throws Exception { + userService.setUserAuthenticated(true); + + request.setMethod("GET"); + request.setRequestURI("/session/00000000/questionids"); + final ModelAndView mav = handlerAdapter.handle(request, response, questionController); + + assertNull(mav); + assertTrue(response.getStatus() == 404); + } + + @Test(expected=UnauthorizedException.class) + public void testShouldNotGetQestionIdsIfUnauthorized() throws Exception { + userService.setUserAuthenticated(false); + + request.setMethod("GET"); + request.setRequestURI("/session/00000000/questionids"); + final ModelAndView mav = handlerAdapter.handle(request, response, questionController); + + assertNull(mav); + assertTrue(response.getStatus() == 401); + } + +} diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index 10f800d1da514247899c5701fc502e53eee683da..74167a3ef484fdd006e922c247517e0627aaf39c 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -163,4 +163,10 @@ public class StubDatabaseDao implements IDatabaseDao { } + @Override + public List<String> getQuestionIds(String sessionKey) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/src/test/java/de/thm/arsnova/services/UserServiceTest.java b/src/test/java/de/thm/arsnova/services/UserServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b4f64bce7538698ea1b9181ef82b2bc68b3e4d69 --- /dev/null +++ b/src/test/java/de/thm/arsnova/services/UserServiceTest.java @@ -0,0 +1,76 @@ +package de.thm.arsnova.services; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import junit.framework.Assert; + +import org.jasig.cas.client.authentication.AttributePrincipalImpl; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.scribe.up.profile.google.Google2AttributesDefinition; +import org.scribe.up.profile.google.Google2Profile; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import de.thm.arsnova.entities.User; + +@RunWith(BlockJUnit4ClassRunner.class) +public class UserServiceTest { + + private static final ConcurrentHashMap<UUID, User> socketid2user = new ConcurrentHashMap<UUID, User>(); + private static final ConcurrentHashMap<String, String> user2session = new ConcurrentHashMap<String, String>(); + + @Test + public void testSocket2UserPersistence() throws IOException, ClassNotFoundException { + socketid2user.put(UUID.randomUUID(), new User(new UsernamePasswordAuthenticationToken("ptsr00", UUID.randomUUID()))); + socketid2user.put(UUID.randomUUID(), new User(new AttributePrincipalImpl("ptstr0"))); + + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Google2AttributesDefinition.EMAIL, "mail@host.com"); + Google2Profile profile = new Google2Profile("ptsr00", attributes); + + socketid2user.put(UUID.randomUUID(), new User(profile)); + List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); + authorities.add(new SimpleGrantedAuthority("ROLE_GUEST")); + socketid2user.put(UUID.randomUUID(), new User(new AnonymousAuthenticationToken("ptsr00", UUID.randomUUID(), authorities))); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(socketid2user); + objOut.close(); + ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); + Map<UUID, String> actual = (Map<UUID, String>) objIn.readObject(); + Assert.assertEquals(actual, socketid2user); + } + + @Test + public void testUser2SessionPersistence() throws IOException, ClassNotFoundException { + user2session.put("ptsr00", UUID.randomUUID().toString()); + user2session.put("ptsr01", UUID.randomUUID().toString()); + user2session.put("ptsr02", UUID.randomUUID().toString()); + user2session.put("ptsr03", UUID.randomUUID().toString()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(user2session); + objOut.close(); + ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); + Map<String, String> actual = (Map<String, String>) objIn.readObject(); + Assert.assertEquals(actual, user2session); + } + + +}