diff --git a/pom.xml b/pom.xml index 092acea79ff08511f3fc0a03ed2514558cdba0b2..16e3abea2e3e420746b702cf83eb67f8d67d7d8d 100644 --- a/pom.xml +++ b/pom.xml @@ -333,7 +333,7 @@ <dependency> <groupId>de.thm.arsnova.connector</groupId> <artifactId>connector-client</artifactId> - <version>0.14.0-SNAPSHOT</version> + <version>0.40.1-SNAPSHOT</version> </dependency> <dependency> diff --git a/src/main/java/de/thm/arsnova/ImageUtils.java b/src/main/java/de/thm/arsnova/ImageUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..0af116547c229c335ee88ca292528365c927cf7c --- /dev/null +++ b/src/main/java/de/thm/arsnova/ImageUtils.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2014 THM webMedia + * + * This file is part of ARSnova. + * + * ARSnova 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 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; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.imageio.ImageIO; + +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Util class for image operations. + * + * @author Daniel Vogel (daniel.vogel@mni.thm.de) + * + */ +public class ImageUtils { + public static final Logger LOGGER = LoggerFactory.getLogger(ImageUtils.class); + + /** + * Converts an image to an Base64 String. + * + * @param imageUrl The image url as a {@link String} + * @return The Base64 {@link String} of the image on success, otherwise <code>null</code>. + */ + public static String encodeImageToString(String imageUrl) { + + String[] urlParts = imageUrl.split("\\."); + StringBuilder result = new StringBuilder(); + + // get format + // + // The format is read dynamically. We have to take control + // in the frontend that no unsupported formats are transmitted! + if ( urlParts.length > 0 ) { + + String extension = urlParts[urlParts.length-1]; + + result.append("data:image/" + extension + ";base64,"); + result.append(Base64.encodeBase64String(convertFileToByteArray(imageUrl))); + + return result.toString(); + } + + return null; + } + + /** + * Gets the bytestream of an image url. + * s + * @param imageUrl The image url as a {@link String} + * @return The <code>byte[]</code> of the image on success, otherwise <code>null</code>. + */ + public static byte[] convertImageToByteArray(String imageUrl, String extension) { + + try { + URL url = new URL(imageUrl); + BufferedImage image = ImageIO.read(url); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + ImageIO.write(image, extension, baos); + + baos.flush(); + baos.close(); + return baos.toByteArray(); + + } catch (MalformedURLException e) { + LOGGER.error(e.getLocalizedMessage()); + } catch (IOException e) { + LOGGER.error(e.getLocalizedMessage()); + } + + return null; + } + + /** + * Gets the bytestream of an image url. + * s + * @param imageUrl The image url as a {@link String} + * @return The <code>byte[]</code> of the image on success, otherwise <code>null</code>. + */ + public static byte[] convertFileToByteArray(String imageUrl) { + + try { + URL url = new URL(imageUrl); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + InputStream is = url.openStream(); + byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time. + int n; + + while ( (n = is.read(byteChunk)) > 0 ) { + baos.write(byteChunk, 0, n); + } + + baos.flush(); + baos.close(); + + return baos.toByteArray(); + + } catch (MalformedURLException e) { + LOGGER.error(e.getLocalizedMessage()); + } catch (IOException e) { + LOGGER.error(e.getLocalizedMessage()); + } + + return null; + } +} + diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java index 525bd65ddea5469aed9cca1da4301d66c3749d3a..b8443784bf35398a46b3845e246b7f97b5ae019e 100644 --- a/src/main/java/de/thm/arsnova/controller/SessionController.java +++ b/src/main/java/de/thm/arsnova/controller/SessionController.java @@ -191,6 +191,24 @@ public class SessionController extends AbstractController { return null; } + @RequestMapping(value = "/{sessionkey}/learningprogress", method = RequestMethod.GET) + @ResponseBody + public final int learningProgress( + @PathVariable final String sessionkey, + final HttpServletResponse response + ) { + return sessionService.getLearningProgress(sessionkey); + } + + @RequestMapping(value = "/{sessionkey}/mylearningprogress", method = RequestMethod.GET) + @ResponseBody + public final int myLearningProgress( + @PathVariable final String sessionkey, + final HttpServletResponse response + ) { + return sessionService.getMyLearningProgress(sessionkey); + } + /* internal redirections */ @RequestMapping(value = "/{sessionKey}/lecturerquestion") diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index ae721ae3660ba4c0587d506c1c4a1639080867ac..28ff837d321414e12a645f32e0f3bcfa83b3b640 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -289,6 +289,12 @@ public class CouchDBDao implements IDatabaseDao { q.put("showStatistic", question.isShowStatistic()); q.put("showAnswer", question.isShowAnswer()); q.put("abstention", question.isAbstention()); + q.put("image", question.getImage()); + q.put("gridSize", question.getGridSize()); + q.put("offsetX", question.getOffsetX()); + q.put("offsetY", question.getOffsetY()); + q.put("zoomLvl", question.getZoomLvl()); + return q; } @@ -306,6 +312,11 @@ public class CouchDBDao implements IDatabaseDao { q.put("showStatistic", question.isShowStatistic()); q.put("showAnswer", question.isShowAnswer()); q.put("abstention", question.isAbstention()); + q.put("image", question.getImage()); + q.put("gridSize", question.getGridSize()); + q.put("offsetX", question.getOffsetX()); + q.put("offsetY", question.getOffsetY()); + q.put("zoomLvl", question.getZoomLvl()); this.database.saveDocument(q); question.set_rev(q.getRev()); @@ -354,7 +365,8 @@ public class CouchDBDao implements IDatabaseDao { results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"), Question.class ); - JSONArray possibleAnswers = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value") + JSONArray possibleAnswers = new JSONArray(); + possibleAnswers = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value") .getJSONArray("possibleAnswers"); Collection<PossibleAnswer> answers = JSONArray.toCollection( possibleAnswers, @@ -924,6 +936,7 @@ public class CouchDBDao implements IDatabaseDao { a.put("questionId", answer.getQuestionId()); a.put("answerSubject", answer.getAnswerSubject()); a.put("questionVariant", answer.getQuestionVariant()); + a.put("questionValue", answer.getQuestionValue()); a.put("answerText", answer.getAnswerText()); a.put("timestamp", answer.getTimestamp()); a.put("user", user.getUsername()); @@ -947,6 +960,7 @@ public class CouchDBDao implements IDatabaseDao { a.put("answerText", answer.getAnswerText()); a.put("timestamp", answer.getTimestamp()); a.put("abstention", answer.isAbstention()); + a.put("questionValue", answer.getQuestionValue()); this.database.saveDocument(a); answer.set_rev(a.getRev()); return answer; @@ -1408,4 +1422,38 @@ public class CouchDBDao implements IDatabaseDao { return false; } + + public int getLearningProgress(Session session) { + NovaView courseView = new NovaView("learning_progress/course_value"); + NovaView maximumView = new NovaView("learning_progress/maximum_value"); + courseView.setKey(session.get_id()); + maximumView.setKey(session.get_id()); + + return getProgressPercentage(courseView, maximumView); + } + + @Override + public int getMyLearningProgress(Session session, User user) { + NovaView userView = new NovaView("learning_progress/user_value"); + 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(); + if (maximumValue.isEmpty()) { + return 0; + } + 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); + return percentage < 0 ? 0 : percentage; + } } diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java index 4bb273c40e83b567071c783f282f99b5baa01dc6..e4697f4018717134195c7787bec8c4c41d34f8f4 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -168,4 +168,8 @@ public interface IDatabaseDao { DbUser getUser(String username); boolean deleteUser(DbUser dbUser); + + int getLearningProgress(Session session); + + int getMyLearningProgress(Session session, User user); } diff --git a/src/main/java/de/thm/arsnova/entities/Answer.java b/src/main/java/de/thm/arsnova/entities/Answer.java index aed482cfba76aac0f3f915fcba3d21b117af4579..d2361ed901256dfb1906f059d87ef92d6ffea750 100644 --- a/src/main/java/de/thm/arsnova/entities/Answer.java +++ b/src/main/java/de/thm/arsnova/entities/Answer.java @@ -10,6 +10,7 @@ public class Answer { private String answerText; private String answerSubject; private String questionVariant; + private int questionValue; private int piRound; private String user; private long timestamp; @@ -133,6 +134,14 @@ public class Answer { this.questionVariant = questionVariant; } + public int getQuestionValue() { + return questionValue; + } + + public void setQuestionValue(int questionValue) { + this.questionValue = questionValue; + } + @Override public final String toString() { return "Answer type:'" + type + "'" diff --git a/src/main/java/de/thm/arsnova/entities/PossibleAnswer.java b/src/main/java/de/thm/arsnova/entities/PossibleAnswer.java index acfea0d3de09a13c2d1e469de0963c85714d110d..ebc36f98e9c2f88d9ac05668ae808a01170289fb 100644 --- a/src/main/java/de/thm/arsnova/entities/PossibleAnswer.java +++ b/src/main/java/de/thm/arsnova/entities/PossibleAnswer.java @@ -23,6 +23,7 @@ public class PossibleAnswer { private String id; private String text; private boolean correct; + private int value; public String getId() { return this.id; @@ -48,6 +49,14 @@ public class PossibleAnswer { this.correct = correct; } + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + @Override public String toString() { return "PossibleAnswer [id=" + id + ", text=" + text + ", correct=" + correct + "]"; diff --git a/src/main/java/de/thm/arsnova/entities/Question.java b/src/main/java/de/thm/arsnova/entities/Question.java index 33c2e59a14ac3385e6f4e44cf695a80a3c0b8d47..8b2d36e30c75c655eec2f7fdc76b95bffe0060fe 100644 --- a/src/main/java/de/thm/arsnova/entities/Question.java +++ b/src/main/java/de/thm/arsnova/entities/Question.java @@ -44,6 +44,12 @@ public class Question { private String _id; private String _rev; + private String image; + private int gridSize; + private int offsetX; + private int offsetY; + private int zoomLvl; + public final String getType() { return type; } @@ -212,6 +218,46 @@ public class Question { this._rev = _rev; } + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public int getGridSize() { + return gridSize; + } + + public void setGridSize(int gridSize) { + this.gridSize = gridSize; + } + + public int getOffsetX() { + return offsetX; + } + + public void setOffsetX(int offsetX) { + this.offsetX = offsetX; + } + + public int getOffsetY() { + return offsetY; + } + + public void setOffsetY(int offsetY) { + this.offsetY = offsetY; + } + + public int getZoomLvl() { + return zoomLvl; + } + + public void setZoomLvl(int zoomLvl) { + this.zoomLvl = zoomLvl; + } + @Override public final String toString() { return "Question type '" + this.type + "': " + this.subject + ";\n" + this.text + this.possibleAnswers; diff --git a/src/main/java/de/thm/arsnova/services/ISessionService.java b/src/main/java/de/thm/arsnova/services/ISessionService.java index d868e4bc1b75c68de8986bcdb7f5bb9fb2f85f7a..611f3ce91aece07210e2472c8f709316a05f80ad 100644 --- a/src/main/java/de/thm/arsnova/services/ISessionService.java +++ b/src/main/java/de/thm/arsnova/services/ISessionService.java @@ -51,4 +51,8 @@ public interface ISessionService { Session updateSession(String sessionkey, Session session); void deleteSession(String sessionkey, User user); + + int getLearningProgress(String sessionkey); + + int getMyLearningProgress(String sessionkey); } diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java index 0467de78e4aa89783df70616385df70ea61b6aab..f91da75e999fb8f84ae0589072373c8325b2a9a1 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -24,9 +24,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +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.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; @@ -35,6 +39,7 @@ import de.thm.arsnova.entities.InterposedReadingCount; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; +import de.thm.arsnova.exceptions.BadRequestException; import de.thm.arsnova.exceptions.ForbiddenException; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.exceptions.UnauthorizedException; @@ -51,6 +56,11 @@ 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) { this.databaseDao = databaseDao; @@ -86,6 +96,25 @@ 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); + if (question.getImage().startsWith("http")) { + String base64ImageString = ImageUtils.encodeImageToString(question.getImage()); + if (base64ImageString == null) { + throw new BadRequestException(); + } + 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 ) { + LOGGER.error("Could not save file. File is too large with "+ fileSize + " Byte."); + throw new BadRequestException(); + } + } Question result = this.databaseDao.saveQuestion(session, question); socketIoServer.reportLecturerQuestionAvailable(result.getSessionKeyword(), result.get_id()); diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java index e9e6af9b97eb11a115f681484eebdfca9a5ecc57..205ee49b743cfafe17347bbed23d3c8deca2323e 100644 --- a/src/main/java/de/thm/arsnova/services/SessionService.java +++ b/src/main/java/de/thm/arsnova/services/SessionService.java @@ -256,4 +256,19 @@ public class SessionService implements ISessionService { } databaseDao.deleteSession(session); } + + @Override + @Authenticated + public int getLearningProgress(String sessionkey) { + Session session = databaseDao.getSession(sessionkey); + return databaseDao.getLearningProgress(session); + } + + @Override + @Authenticated + public int getMyLearningProgress(String sessionkey) { + Session session = databaseDao.getSession(sessionkey); + User user = userService.getCurrentUser(); + return databaseDao.getMyLearningProgress(session, user); + } } diff --git a/src/main/java/de/thm/arsnova/web/CorsFilter.java b/src/main/java/de/thm/arsnova/web/CorsFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..fc2e55f393103ae8fbbb6d17df6a05f4fa61af12 --- /dev/null +++ b/src/main/java/de/thm/arsnova/web/CorsFilter.java @@ -0,0 +1,29 @@ +package de.thm.arsnova.web; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +public class CorsFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + response.addHeader("Access-Control-Allow-Credentials", "true"); + response.addHeader("Access-Control-Allow-Methods", "GET"); + response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With"); + + if (request.getHeader("origin") != null) { + response.addHeader("Access-Control-Allow-Origin", request.getHeader("origin")); + } + + filterChain.doFilter(request, response); + } +} diff --git a/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml b/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml index 9c20a5817520dbc5707fd3750cc786f7a739d5ef..1c3c4a18ef671d045bd04421cf4ba5e9590be830 100644 --- a/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml +++ b/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml @@ -11,56 +11,65 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- ARSnova Servlet Context --> - - <context:component-scan base-package="de.thm.arsnova.controller" /> + + <context:component-scan base-package="de.thm.arsnova.controller,de.thm.arsnova.web" /> <context:property-placeholder location="file:///etc/arsnova/arsnova.properties" file-encoding="UTF-8" /> - <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /> - - <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> - <property name="favorPathExtension" value="false" /> - <property name="favorParameter" value="true" /> - <property name="mediaTypes" > - <value> - html=text/html - json=application/json - </value> - </property> + <mvc:annotation-driven + content-negotiation-manager="contentNegotiationManager" /> + + <bean id="contentNegotiationManager" + class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> + <property name="favorPathExtension" value="false" /> + <property name="favorParameter" value="true" /> + <property name="mediaTypes"> + <value> + html=text/html + json=application/json + </value> + </property> </bean> <mvc:annotation-driven /> <mvc:resources mapping="/**" location="/" /> - + <!-- --> - <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> - <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> + <bean + class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> + <bean + class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> - <bean class = "org.springframework.http.converter.StringHttpMessageConverter"> - <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" /> - </bean> - <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> + <bean + class="org.springframework.http.converter.StringHttpMessageConverter"> + <property name="supportedMediaTypes" value="text/plain;charset=UTF-8" /> + </bean> + <bean + class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> </list> </property> </bean> <!-- --> - <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> - <property name="viewResolvers"> - <list> - <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> - <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> - <property name="prefix" value="/WEB-INF/jsp/"/> - <property name="suffix" value=".jsp"/> - </bean> - </list> - </property> - <property name="defaultViews"> - <list> - <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"> - <property name="prefixJson" value="false"/> - </bean> - </list> - </property> + <bean + class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> + <property name="viewResolvers"> + <list> + <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> + <property name="viewClass" + value="org.springframework.web.servlet.view.JstlView" /> + <property name="prefix" value="/WEB-INF/jsp/" /> + <property name="suffix" value=".jsp" /> + </bean> + </list> + </property> + <property name="defaultViews"> + <list> + <bean + class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"> + <property name="prefixJson" value="false" /> + </bean> + </list> + </property> </bean> - + </beans> diff --git a/src/main/webapp/WEB-INF/spring/spring-main.xml b/src/main/webapp/WEB-INF/spring/spring-main.xml index 384e0a721d19bd74bc2d7e12a5cb73fdc4f14c26..72d0f00e72f8cc69868a1949b1070d03a38b029e 100644 --- a/src/main/webapp/WEB-INF/spring/spring-main.xml +++ b/src/main/webapp/WEB-INF/spring/spring-main.xml @@ -25,14 +25,14 @@ </property> <property name="fileEncoding" value="UTF-8" /> </bean> - + <import resource="spring-security.xml" /> <context:component-scan base-package="de.thm.arsnova.dao,de.thm.arsnova.events,de.thm.arsnova.security,de.thm.arsnova.services" /> <context:annotation-config /> <task:annotation-driven /> - + <aop:aspectj-autoproxy> <aop:include name="authorizationAdviser" /> <aop:include name="userSessionAspect" /> @@ -42,11 +42,11 @@ init-method="startServer" destroy-method="stopServer" scope="singleton" 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="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 8ebba29fa000ab97ff476a88dd6dc00bcb439785..75b4f85dfa2d9be9d897517d4ce23c473a78bce5 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -58,6 +58,15 @@ <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> + <filter> + <filter-name>corsFilter</filter-name> + <filter-class>de.thm.arsnova.web.CorsFilter</filter-class> + </filter> + <filter-mapping> + <filter-name>corsFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <mime-mapping> <extension>manifest</extension> <mime-type>text/cache-manifest</mime-type> diff --git a/src/main/webapp/arsnova.properties.example b/src/main/webapp/arsnova.properties.example index 76a0efbc0476e43aae1c6b97b698ab0c8ea79ce0..9fa91c0b6001648560e0fdf8ca60d7599a149e55 100644 --- a/src/main/webapp/arsnova.properties.example +++ b/src/main/webapp/arsnova.properties.example @@ -60,6 +60,9 @@ mail.host= # minutes, after which the feedback is deleted feedback.cleanup=10 +# maximal filesize in bytes +upload.filesize_b=1048576 + couchdb.host=localhost couchdb.port=5984 couchdb.name=arsnova diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index a93f1bcc38a4720e6558a76d6a55c374798829f8..dbc071b24c46faa3d3bbf49608f48c8a62dd23cf 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -510,4 +510,16 @@ public class StubDatabaseDao implements IDatabaseDao { // TODO Auto-generated method stub return null; } + + @Override + public int getLearningProgress(Session session) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getMyLearningProgress(Session session, User user) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/src/test/resources/arsnova.properties.example b/src/test/resources/arsnova.properties.example index 76a0efbc0476e43aae1c6b97b698ab0c8ea79ce0..9fa91c0b6001648560e0fdf8ca60d7599a149e55 100644 --- a/src/test/resources/arsnova.properties.example +++ b/src/test/resources/arsnova.properties.example @@ -60,6 +60,9 @@ mail.host= # minutes, after which the feedback is deleted feedback.cleanup=10 +# maximal filesize in bytes +upload.filesize_b=1048576 + couchdb.host=localhost couchdb.port=5984 couchdb.name=arsnova