/* * This file is part of ARSnova Backend. * Copyright (C) 2012-2017 The ARSnova Team * * ARSnova Backend is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ARSnova Backend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.thm.arsnova.controller; import de.thm.arsnova.connector.model.Course; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.SessionFeature; import de.thm.arsnova.entities.SessionInfo; import de.thm.arsnova.entities.transport.ImportExportSession; import de.thm.arsnova.entities.transport.LearningProgressValues; import de.thm.arsnova.exceptions.UnauthorizedException; import de.thm.arsnova.services.ISessionService; import de.thm.arsnova.services.IUserService; import de.thm.arsnova.services.SessionService.SessionInfoNameComparator; import de.thm.arsnova.services.SessionService.SessionInfoShortNameComparator; import de.thm.arsnova.services.SessionService.SessionNameComparator; import de.thm.arsnova.services.SessionService.SessionShortNameComparator; import de.thm.arsnova.web.DeprecatedApi; import de.thm.arsnova.web.Pagination; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Handles requests related to ARSnova sessions. */ @RestController @RequestMapping("/session") @Api(value = "/session", description = "the Session Controller API") public class SessionController extends PaginationController { @Autowired private ISessionService sessionService; @Autowired private IUserService userService; @ApiOperation(value = "join a session", nickname = "joinSession") @DeprecatedApi @Deprecated @RequestMapping(value = "/{sessionkey}", method = RequestMethod.GET) public Session joinSession( @ApiParam(value = "Session-Key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "Adminflag", required = false) @RequestParam(value = "admin", defaultValue = "false") final boolean admin ) { if (admin) { return sessionService.getSessionForAdmin(sessionkey); } else { return sessionService.getSession(sessionkey); } } @ApiOperation(value = "deletes a session", nickname = "deleteSession") @RequestMapping(value = "/{sessionkey}", method = RequestMethod.DELETE) public void deleteSession(@ApiParam(value = "Session-Key from current session", required = true) @PathVariable final String sessionkey) { sessionService.deleteSession(sessionkey); } @ApiOperation(value = "count active users", nickname = "countActiveUsers") @DeprecatedApi @Deprecated @RequestMapping(value = "/{sessionkey}/activeusercount", method = RequestMethod.GET) public int countActiveUsers(@ApiParam(value = "Session-Key from current session", required = true) @PathVariable final String sessionkey) { return sessionService.activeUsers(sessionkey); } @ApiOperation(value = "Creates a new Session and returns the Session's data", nickname = "postNewSession") @ApiResponses(value = { @ApiResponse(code = 201, message = HTML_STATUS_201), @ApiResponse(code = 503, message = HTML_STATUS_503) }) @RequestMapping(value = "/", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) public Session postNewSession(@ApiParam(value = "current session", required = true) @RequestBody final Session session, final HttpServletResponse response) { if (session != null && session.isCourseSession()) { final List<Course> courses = new ArrayList<>(); final Course course = new Course(); course.setId(session.getCourseId()); courses.add(course); final int sessionCount = sessionService.countSessions(courses); if (sessionCount > 0) { final String appendix = " (" + (sessionCount + 1) + ")"; session.setName(session.getName() + appendix); session.setShortName(session.getShortName() + appendix); } } final Session newSession = sessionService.saveSession(session); if (newSession == null) { response.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value()); return null; } return newSession; } @ApiOperation(value = "updates a session", nickname = "postNewSession") @RequestMapping(value = "/{sessionkey}", method = RequestMethod.PUT) public Session updateSession( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "current session", required = true) @RequestBody final Session session ) { return sessionService.updateSession(sessionkey, session); } @ApiOperation(value = "change the session creator (owner)", nickname = "changeSessionCreator") @RequestMapping(value = "/{sessionkey}/changecreator", method = RequestMethod.PUT) public Session changeSessionCreator( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "new session creator", required = true) @RequestBody final String newCreator ) { return sessionService.changeSessionCreator(sessionkey, newCreator); } @ApiOperation(value = "Retrieves a list of Sessions", nickname = "getSessions") @ApiResponses(value = { @ApiResponse(code = 204, message = HTML_STATUS_204), @ApiResponse(code = 501, message = HTML_STATUS_501) }) @RequestMapping(value = "/", method = RequestMethod.GET) @Pagination public List<Session> getSessions( @ApiParam(value = "ownedOnly", required = true) @RequestParam(value = "ownedonly", defaultValue = "false") final boolean ownedOnly, @ApiParam(value = "visitedOnly", required = true) @RequestParam(value = "visitedonly", defaultValue = "false") final boolean visitedOnly, @ApiParam(value = "sortby", required = true) @RequestParam(value = "sortby", defaultValue = "name") final String sortby, @ApiParam(value = "for a given username. admin rights needed", required = false) @RequestParam(value = "username", defaultValue = "") final String username, final HttpServletResponse response ) { List<Session> sessions; if (!"".equals(username)) { try { if (ownedOnly && !visitedOnly) { sessions = sessionService.getUserSessions(username); } else if (visitedOnly && !ownedOnly) { sessions = sessionService.getUserVisitedSessions(username); } else { response.setStatus(HttpStatus.NOT_IMPLEMENTED.value()); return null; } } catch (final AccessDeniedException e) { throw new UnauthorizedException(); } } else { /* TODO implement all parameter combinations, implement use of user parameter */ try { if (ownedOnly && !visitedOnly) { sessions = sessionService.getMySessions(offset, limit); } else if (visitedOnly && !ownedOnly) { sessions = sessionService.getMyVisitedSessions(offset, limit); } else { response.setStatus(HttpStatus.NOT_IMPLEMENTED.value()); return null; } } catch (final AccessDeniedException e) { throw new UnauthorizedException(); } } if (sessions == null || sessions.isEmpty()) { response.setStatus(HttpServletResponse.SC_NO_CONTENT); return null; } if ("shortname".equals(sortby)) { Collections.sort(sessions, new SessionShortNameComparator()); } else { Collections.sort(sessions, new SessionNameComparator()); } return sessions; } /** * Returns a list of my own sessions with only the necessary information like name, keyword, or counters. */ @ApiOperation(value = "Retrieves a Session", nickname = "getMySessions") @ApiResponses(value = { @ApiResponse(code = 204, message = HTML_STATUS_204) }) @RequestMapping(value = "/", method = RequestMethod.GET, params = "statusonly=true") @Pagination public List<SessionInfo> getMySessions( @ApiParam(value = "visitedOnly", required = true) @RequestParam(value = "visitedonly", defaultValue = "false") final boolean visitedOnly, @ApiParam(value = "sort by", required = false) @RequestParam(value = "sortby", defaultValue = "name") final String sortby, final HttpServletResponse response ) { List<SessionInfo> sessions; if (!visitedOnly) { sessions = sessionService.getMySessionsInfo(offset, limit); } else { sessions = sessionService.getMyVisitedSessionsInfo(offset, limit); } if (sessions == null || sessions.isEmpty()) { response.setStatus(HttpServletResponse.SC_NO_CONTENT); return null; } if ("shortname".equals(sortby)) { Collections.sort(sessions, new SessionInfoShortNameComparator()); } else { Collections.sort(sessions, new SessionInfoNameComparator()); } return sessions; } @ApiOperation(value = "Retrieves all public pool sessions for the current user", nickname = "getMyPublicPoolSessions") @ApiResponses(value = { @ApiResponse(code = 204, message = HTML_STATUS_204) }) @RequestMapping(value = "/publicpool", method = RequestMethod.GET, params = "statusonly=true") public List<SessionInfo> getMyPublicPoolSessions( final HttpServletResponse response ) { List<SessionInfo> sessions = sessionService.getMyPublicPoolSessionsInfo(); if (sessions == null || sessions.isEmpty()) { response.setStatus(HttpServletResponse.SC_NO_CONTENT); return null; } return sessions; } @ApiOperation(value = "Retrieves all public pool sessions", nickname = "getMyPublicPoolSessions") @ApiResponses(value = { @ApiResponse(code = 204, message = HTML_STATUS_204) }) @RequestMapping(value = "/publicpool", method = RequestMethod.GET) public List<SessionInfo> getPublicPoolSessions( final HttpServletResponse response ) { List<SessionInfo> sessions = sessionService.getPublicPoolSessionsInfo(); if (sessions == null || sessions.isEmpty()) { response.setStatus(HttpServletResponse.SC_NO_CONTENT); return null; } return sessions; } @ApiOperation(value = "imports a session", nickname = "importSession") @RequestMapping(value = "/import", method = RequestMethod.POST) public SessionInfo importSession( @ApiParam(value = "current session", required = true) @RequestBody final ImportExportSession session, final HttpServletResponse response ) { return sessionService.importSession(session); } @ApiOperation(value = "export sessions", nickname = "exportSession") @RequestMapping(value = "/export", method = RequestMethod.GET) public List<ImportExportSession> getExport( @ApiParam(value = "sessionkey", required = true) @RequestParam(value = "sessionkey", defaultValue = "") final List<String> sessionkey, @ApiParam(value = "wether statistics shall be exported", required = true) @RequestParam(value = "withAnswerStatistics", defaultValue = "false") final Boolean withAnswerStatistics, @ApiParam(value = "wether interposed questions shall be exported", required = true) @RequestParam(value = "withFeedbackQuestions", defaultValue = "false") final Boolean withFeedbackQuestions, final HttpServletResponse response ) { List<ImportExportSession> sessions = new ArrayList<>(); ImportExportSession temp; for (String key : sessionkey) { sessionService.setActive(key, false); temp = sessionService.exportSession(key, withAnswerStatistics, withFeedbackQuestions); if (temp != null) { sessions.add(temp); } sessionService.setActive(key, true); } return sessions; } @ApiOperation(value = "copy a session to the public pool if enabled") @RequestMapping(value = "/{sessionkey}/copytopublicpool", method = RequestMethod.POST) public SessionInfo copyToPublicPool( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "public pool attributes for session", required = true) @RequestBody final de.thm.arsnova.entities.transport.ImportExportSession.PublicPool publicPool ) { sessionService.setActive(sessionkey, false); SessionInfo sessionInfo = sessionService.copySessionToPublicPool(sessionkey, publicPool); sessionService.setActive(sessionkey, true); return sessionInfo; } @ApiOperation(value = "Locks or unlocks a Session", nickname = "lockSession") @ApiResponses(value = { @ApiResponse(code = 404, message = HTML_STATUS_404) }) @RequestMapping(value = "/{sessionkey}/lock", method = RequestMethod.POST) public Session lockSession( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "lock", required = true) @RequestParam(required = false) final Boolean lock, final HttpServletResponse response ) { if (lock != null) { return sessionService.setActive(sessionkey, lock); } response.setStatus(HttpStatus.NOT_FOUND.value()); return null; } @ApiOperation(value = "retrieves a value for the learning progress", nickname = "getLearningProgress") @RequestMapping(value = "/{sessionkey}/learningprogress", method = RequestMethod.GET) public LearningProgressValues getLearningProgress( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "progress type", required = false) @RequestParam(value = "type", defaultValue = "questions") final String progressType, @ApiParam(value = "question variant", required = false) @RequestParam(value = "questionVariant", required = false) final String questionVariant, final HttpServletResponse response ) { return sessionService.getLearningProgress(sessionkey, progressType, questionVariant); } @ApiOperation(value = "retrieves a value for the learning progress for the current user", nickname = "getMyLearningProgress") @RequestMapping(value = "/{sessionkey}/mylearningprogress", method = RequestMethod.GET) public LearningProgressValues getMyLearningProgress( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @RequestParam(value = "type", defaultValue = "questions") final String progressType, @RequestParam(value = "questionVariant", required = false) final String questionVariant, final HttpServletResponse response ) { return sessionService.getMyLearningProgress(sessionkey, progressType, questionVariant); } @ApiOperation(value = "retrieves all session features", nickname = "getSessionFeatures") @RequestMapping(value = "/{sessionkey}/features", method = RequestMethod.GET) public SessionFeature getSessionFeatures( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, final HttpServletResponse response ) { return sessionService.getSessionFeatures(sessionkey); } @RequestMapping(value = "/{sessionkey}/features", method = RequestMethod.PUT) @ApiOperation(value = "change all session features", nickname = "changeSessionFeatures") public SessionFeature changeSessionFeatures( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "session feature", required = true) @RequestBody final SessionFeature features, final HttpServletResponse response ) { return sessionService.changeSessionFeatures(sessionkey, features); } @RequestMapping(value = "/{sessionkey}/lockfeedbackinput", method = RequestMethod.POST) @ApiOperation(value = "locks input of user live feedback", nickname = "lockFeedbackInput") public boolean lockFeedbackInput( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "lock", required = true) @RequestParam(required = true) final Boolean lock, final HttpServletResponse response ) { return sessionService.lockFeedbackInput(sessionkey, lock); } @RequestMapping(value = "/{sessionkey}/flipflashcards", method = RequestMethod.POST) @ApiOperation(value = "flip all flashcards in session", nickname = "lockFeedbackInput") public boolean flipFlashcards( @ApiParam(value = "session-key from current session", required = true) @PathVariable final String sessionkey, @ApiParam(value = "flip", required = true) @RequestParam(required = true) final Boolean flip, final HttpServletResponse response ) { return sessionService.flipFlashcards(sessionkey, flip); } /* internal redirections */ @RequestMapping(value = "/{sessionKey}/lecturerquestion") public String redirectLecturerQuestion( @PathVariable final String sessionKey, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/lecturerquestion/?sessionkey=%s", sessionKey); } @RequestMapping(value = "/{sessionKey}/lecturerquestion/{arg1}") public String redirectLecturerQuestionWithOneArgument( @PathVariable final String sessionKey, @PathVariable final String arg1, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/lecturerquestion/%s/?sessionkey=%s", arg1, sessionKey); } @RequestMapping(value = "/{sessionKey}/lecturerquestion/{arg1}/{arg2}") public String redirectLecturerQuestionWithTwoArguments( @PathVariable final String sessionKey, @PathVariable final String arg1, @PathVariable final String arg2, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/lecturerquestion/%s/%s/?sessionkey=%s", arg1, arg2, sessionKey); } @RequestMapping(value = "/{sessionKey}/lecturerquestion/{arg1}/{arg2}/{arg3}") public String redirectLecturerQuestionWithThreeArguments( @PathVariable final String sessionKey, @PathVariable final String arg1, @PathVariable final String arg2, @PathVariable final String arg3, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/lecturerquestion/%s/%s/%s/?sessionkey=%s", arg1, arg2, arg3, sessionKey); } @RequestMapping(value = "/{sessionKey}/audiencequestion") public String redirectAudienceQuestion( @PathVariable final String sessionKey, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/audiencequestion/?sessionkey=%s", sessionKey); } @RequestMapping(value = "/{sessionKey}/audiencequestion/{arg1}") public String redirectAudienceQuestionWithOneArgument( @PathVariable final String sessionKey, @PathVariable final String arg1, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/audiencequestion/%s/?sessionkey=%s", arg1, sessionKey); } @RequestMapping(value = "/{sessionKey}/audiencequestion/{arg1}/{arg2}") public String redirectAudienceQuestionWithTwoArguments( @PathVariable final String sessionKey, @PathVariable final String arg1, @PathVariable final String arg2, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/audiencequestion/%s/%s/?sessionkey=%s", arg1, arg2, sessionKey); } @RequestMapping(value = "/{sessionKey}/audiencequestion/{arg1}/{arg2}/{arg3}") public String redirectAudienceQuestionWithThreeArguments( @PathVariable final String sessionKey, @PathVariable final String arg1, @PathVariable final String arg2, @PathVariable final String arg3, final HttpServletResponse response ) { response.addHeader(X_FORWARDED, "1"); return String.format("forward:/audiencequestion/%s/%s/%s/?sessionkey=%s", arg1, arg2, arg3, sessionKey); } }