diff --git a/src/main/java/de/thm/arsnova/controller/MotdController.java b/src/main/java/de/thm/arsnova/controller/MotdController.java new file mode 100644 index 0000000000000000000000000000000000000000..5f56ec19aceb3c72d3d091ee0935d4911279a6b3 --- /dev/null +++ b/src/main/java/de/thm/arsnova/controller/MotdController.java @@ -0,0 +1,177 @@ +/* + * This file is part of ARSnova Backend. + * Copyright (C) 2012-2015 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 java.util.Date; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; + +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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 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 de.thm.arsnova.entities.Motd; +import de.thm.arsnova.entities.MotdList; +import de.thm.arsnova.exceptions.NotFoundException; +import de.thm.arsnova.services.IMotdService; + +/** + * + */ +@RestController +@RequestMapping("/motd") +@Api(value = "/motd", description = "the Motd Controller API") +public class MotdController extends AbstractController { + + private static final Logger LOGGER = LoggerFactory.getLogger(MotdController.class); + + @Autowired + private IMotdService motdService; + + @ApiOperation(value = "get messages. if adminview=false, only messages with startdate<clientdate<enddate are returned") + @RequestMapping(value = "/", method = RequestMethod.GET) + @ApiResponses(value = { + @ApiResponse(code = 204, message = HTML_STATUS_204), + @ApiResponse(code = 501, message = HTML_STATUS_501) + }) + public List<Motd> getMotd( + @ApiParam(value = "clientdate", required = false) @RequestParam(value = "clientdate", defaultValue = "") final String clientdate, + @ApiParam(value = "adminview", required = false) @RequestParam(value = "adminview", defaultValue = "false") final Boolean adminview, + @ApiParam(value = "audience", required = false) @RequestParam(value = "audience", defaultValue = "all") final String audience, + @ApiParam(value = "sessionkey", required = false) @RequestParam(value = "sessionkey", defaultValue = "null") final String sessionkey + ) { + List<Motd> motds = new ArrayList<Motd>(); + Date client = new Date(System.currentTimeMillis()); + if (!clientdate.isEmpty()) { + client.setTime(Long.parseLong(clientdate)); + } + if (adminview) { + if (sessionkey.equals("null")) { + motds = motdService.getAdminMotds(); + } + else { + motds = motdService.getAllSessionMotds(sessionkey); + } + } + else { + motds = motdService.getCurrentMotds(client, audience, sessionkey); + } + return motds; + } + + @ApiOperation(value = "create a new message of the day", nickname = "createMotd") + @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 Motd postNewMotd( + @ApiParam(value = "current motd", required = true) @RequestBody final Motd motd, + @ApiParam(value = "http servlet response", required = true) final HttpServletResponse response + ) { + if (motd != null) { + Motd newMotd = new Motd(); + if (motd.getAudience().equals("session") && motd.getSessionkey() != null) { + newMotd = motdService.saveSessionMotd(motd.getSessionkey(), motd); + } + else { + newMotd = motdService.saveMotd(motd); + } + if (newMotd == null) { + response.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value()); + return null; + } + return newMotd; + } + else { + response.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value()); + return null; + } + } + + @ApiOperation(value = "update a message of the day", nickname = "updateMotd") + @RequestMapping(value = "/{motdkey}", method = RequestMethod.PUT) + public Motd updateMotd( + @ApiParam(value = "motdkey from current motd", required = true) @PathVariable final String motdkey, + @ApiParam(value = "current motd", required = true) @RequestBody final Motd motd + ) { + if (motd.getAudience().equals("session") && motd.getSessionkey() != null) { + return motdService.updateSessionMotd(motd.getSessionkey(), motd); + } + else { + return motdService.updateMotd(motd); + } + } + + @ApiOperation(value = "deletes a message of the day", nickname = "deleteMotd") + @RequestMapping(value = "/{motdkey}", method = RequestMethod.DELETE) + public void deleteMotd(@ApiParam(value = "Motd-key from the message that shall be deleted", required = true) @PathVariable final String motdkey) { + Motd motd = motdService.getMotd(motdkey); + if (motd.getAudience().equals("session")) { + motdService.deleteSessionMotd(motd.getSessionkey(), motd); + } + else { + motdService.deleteMotd(motd); + } + } + + @ApiOperation(value = "get a list of the motdkeys the current user has confirmed to be read") + @RequestMapping(value = "/userlist", method = RequestMethod.GET) + public MotdList getUserMotdList( + @ApiParam(value = "users name", required = true) @RequestParam(value = "username", defaultValue = "null", required = true) final String username) { + return motdService.getMotdListForUser(username); + } + + @ApiOperation(value = "create a list of the motdkeys the current user has confirmed to be read") + @RequestMapping(value = "/userlist", method = RequestMethod.POST) + public MotdList postUserMotdList( + @ApiParam(value = "current motdlist", required = true) @RequestBody final MotdList userMotdList + ) { + return motdService.saveUserMotdList(userMotdList); + } + + @ApiOperation(value = "update a list of the motdkeys the current user has confirmed to be read") + @RequestMapping(value = "/userlist", method = RequestMethod.PUT) + public MotdList updateUserMotdList( + @ApiParam(value = "current motdlist", required = true) @RequestBody final MotdList userMotdList + ) { + return motdService.updateUserMotdList(userMotdList); + } +} diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index 153319dc7d0e77914a5c9b53195f95c72ca3c06b..49a4a07701fae233b1a2a777bd5b01d70f2ed7ff 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -29,6 +29,8 @@ import java.util.Map.Entry; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.Date; +import java.util.StringTokenizer; import net.sf.ezmorph.Morpher; import net.sf.ezmorph.MorpherRegistry; @@ -81,6 +83,8 @@ import de.thm.arsnova.entities.transport.ImportExportSession.ImportExportQuestio import de.thm.arsnova.events.NewAnswerEvent; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.ISessionService; +import de.thm.arsnova.entities.Motd; +import de.thm.arsnova.entities.MotdList; /** * Database implementation based on CouchDB. @@ -2334,10 +2338,10 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware view.setIncludeDocs(true); final List<Document> questiondocs = getDatabase().view(view).getResults(); if (questiondocs == null || questiondocs.isEmpty()) { + return null; } final List<Question> result = new ArrayList<Question>(); - final MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry(); final Morpher dynaMorpher = new BeanMorpher(PossibleAnswer.class, morpherRegistry); morpherRegistry.registerMorpher(dynaMorpher); @@ -2370,4 +2374,184 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware } return result; } + + @Override + public List<Motd> getAdminMotds() { + NovaView view = new NovaView("motd/admin"); + return getMotds(view); + } + + @Override + @Cacheable(cacheNames = "motds", key = "'all'") + public List<Motd> getMotdsForAll() { + NovaView view = new NovaView("motd/for_all"); + return getMotds(view); + } + + @Override + @Cacheable(cacheNames = "motds", key = "'loggedIn'") + public List<Motd> getMotdsForLoggedIn() { + NovaView view = new NovaView("motd/for_loggedin"); + return getMotds(view); + } + + @Override + @Cacheable(cacheNames = "motds", key = "'tutors'") + public List<Motd> getMotdsForTutors() { + NovaView view = new NovaView("motd/for_tutors"); + return getMotds(view); + } + + @Override + @Cacheable(cacheNames = "motds", key = "'students'") + public List<Motd> getMotdsForStudents() { + NovaView view = new NovaView("motd/for_students"); + return getMotds(view); + } + + @Override + @Cacheable(cacheNames = "motds", key = "('session').concat(#p0)") + public List<Motd> getMotdsForSession(final String sessionkey) { + NovaView view = new NovaView("motd/by_sessionkey"); + view.setKey(sessionkey); + return getMotds(view); + } + + @Override + public List<Motd> getMotds(NovaView view) { + final ViewResults motddocs = this.getDatabase().view(view); + List<Motd> motdlist = new ArrayList<Motd>(); + for (final Document d : motddocs.getResults()) { + Motd motd = new Motd(); + motd.set_id(d.getId()); + motd.set_rev(d.getJSONObject("value").getString("_rev")); + motd.setMotdkey(d.getJSONObject("value").getString("motdkey")); + Date start = new Date(Long.parseLong(d.getJSONObject("value").getString("startdate"))); + motd.setStartdate(start); + Date end = new Date(Long.parseLong(d.getJSONObject("value").getString("enddate"))); + motd.setEnddate(end); + motd.setTitle(d.getJSONObject("value").getString("title")); + motd.setText(d.getJSONObject("value").getString("text")); + motd.setAudience(d.getJSONObject("value").getString("audience")); + motd.setSessionkey(d.getJSONObject("value").getString("sessionkey")); + motdlist.add(motd); + } + return motdlist; + } + + @Override + public Motd getMotdByKey(String key) { + NovaView view = new NovaView("motd/by_keyword"); + view.setKey(key); + Motd motd = new Motd(); + + ViewResults results = this.getDatabase().view(view); + + for (final Document d : results.getResults()) { + motd.set_id(d.getId()); + motd.set_rev(d.getJSONObject("value").getString("_rev")); + motd.setMotdkey(d.getJSONObject("value").getString("motdkey")); + Date start = new Date(Long.parseLong(d.getJSONObject("value").getString("startdate"))); + motd.setStartdate(start); + Date end = new Date(Long.parseLong(d.getJSONObject("value").getString("enddate"))); + motd.setEnddate(end); + motd.setTitle(d.getJSONObject("value").getString("title")); + motd.setText(d.getJSONObject("value").getString("text")); + motd.setAudience(d.getJSONObject("value").getString("audience")); + motd.setSessionkey(d.getJSONObject("value").getString("sessionkey")); + } + + return motd; + } + + @Override + @CacheEvict(cacheNames = "motds", key = "#p0.audience.concat(#p0.sessionkey)") + public Motd createOrUpdateMotd(Motd motd) { + try { + String id = motd.get_id(); + String rev = motd.get_rev(); + Document d = new Document(); + + if (null != id) { + d = database.getDocument(id, rev); + } + if (motd.getMotdkey() == null) { + motd.setMotdkey(sessionService.generateKeyword()); + } + d.put("type", "motd"); + d.put("motdkey", motd.getMotdkey()); + d.put("startdate", String.valueOf(motd.getStartdate().getTime())); + d.put("enddate", String.valueOf(motd.getEnddate().getTime())); + d.put("title", motd.getTitle()); + d.put("text", motd.getText()); + d.put("audience", motd.getAudience()); + d.put("sessionkey", motd.getSessionkey()); + + database.saveDocument(d, id); + motd.set_id(d.getId()); + motd.set_rev(d.getRev()); + + return motd; + } catch (IOException e) { + LOGGER.error("Could not save motd {}", motd); + } + + return null; + } + + @Override + @CacheEvict(cacheNames = "motds", key = "#p0.audience.concat(#p0.sessionkey)") + public void deleteMotd(Motd motd) { + try { + this.deleteDocument(motd.get_id()); + } catch (IOException e) { + LOGGER.error("Could not delete Motd {}", motd.get_id()); + } + } + + @Override + @Cacheable(cacheNames = "motdlist", key = "#p0") + public MotdList getMotdListForUser(final String username) { + NovaView view = new NovaView("motd/list_by_username"); + view.setKey(username); + + ViewResults results = this.getDatabase().view(view); + + MotdList motdlist = new MotdList(); + for (final Document d : results.getResults()) { + motdlist.set_id(d.getId()); + motdlist.set_rev(d.getJSONObject("value").getString("_rev")); + motdlist.setUsername(d.getJSONObject("value").getString("username")); + motdlist.setMotdkeys(d.getJSONObject("value").getString("motdkeys")); + } + return motdlist; + } + + @Override + @CachePut(cacheNames = "motdlist", key = "#p0.username") + public MotdList createOrUpdateMotdList(MotdList motdlist) { + try { + String id = motdlist.get_id(); + String rev = motdlist.get_rev(); + Document d = new Document(); + + if (null != id) { + d = database.getDocument(id, rev); + } + d.put("type","motdlist"); + d.put("username", motdlist.getUsername()); + d.put("motdkeys", motdlist.getMotdkeys()); + + database.saveDocument(d, id); + motdlist.set_id(d.getId()); + motdlist.set_rev(d.getRev()); + + return motdlist; + } catch (IOException e) { + LOGGER.error("Could not save motdlist {}", motdlist); + } + + 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 3fbfe4231d4cdf6f2a7efcb3c18521d4f6ce133b..0990dfe8c0d94a7167f5f094f3d025401efc5b06 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -33,6 +33,8 @@ import de.thm.arsnova.entities.SortOrder; import de.thm.arsnova.entities.Statistics; import de.thm.arsnova.entities.User; import de.thm.arsnova.entities.transport.ImportExportSession; +import de.thm.arsnova.entities.Motd; +import de.thm.arsnova.entities.MotdList; /** * All methods the database must support. @@ -224,4 +226,28 @@ public interface IDatabaseDao { List<Question> setVotingAdmissionForAllQuestions(Session session, boolean disableVoting); <T> T getObjectFromId(String documentId, Class<T> klass); + + List<Motd> getAdminMotds(); + + List<Motd> getMotdsForAll(); + + List<Motd> getMotdsForLoggedIn(); + + List<Motd> getMotdsForTutors(); + + List<Motd> getMotdsForStudents(); + + List<Motd> getMotdsForSession(final String sessionkey); + + List<Motd> getMotds(NovaView view); + + Motd getMotdByKey(String key); + + Motd createOrUpdateMotd(Motd motd); + + void deleteMotd(Motd motd); + + MotdList getMotdListForUser(final String username); + + MotdList createOrUpdateMotdList(MotdList motdlist); } diff --git a/src/main/java/de/thm/arsnova/entities/Motd.java b/src/main/java/de/thm/arsnova/entities/Motd.java new file mode 100644 index 0000000000000000000000000000000000000000..571d7e4f28f199c43b61f5fb74075caef6a5f0f3 --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/Motd.java @@ -0,0 +1,138 @@ +/* + * This file is part of ARSnova Backend. + * Copyright (C) 2012-2015 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.entities; + +import java.util.Date; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * This class represents a message of the day. + */ +@ApiModel(value = "motd", description = "the message of the day entity") +public class Motd { + + private String motdkey; //ID + private Date startdate; + private Date enddate; + private String title; + private String text; + private String audience; + private String sessionkey; + private String _id; + private String _rev; + + @ApiModelProperty(required = true, value = "the identification string") + public String getMotdkey() { + return motdkey; + } + + public void setMotdkey(final String key) { + motdkey = key; + } + + @ApiModelProperty(required = true, value = "startdate for showing this message (timestamp format)") + public Date getStartdate() { + return startdate; + } + + public void setStartdate(final Date timestamp) { + startdate = timestamp; + } + + @ApiModelProperty(required = true, value = "enddate for showing this message (timestamp format)") + public Date getEnddate() { + return enddate; + } + + public void setEnddate(final Date timestamp) { + enddate = timestamp; + } + + @ApiModelProperty(required = true, value = "tite of the message") + public String getTitle() { + return title; + } + + public void setTitle(final String ttitle) { + title = ttitle; + } + + @ApiModelProperty(required = true, value = "text of the message") + public String getText() { + return text; + } + + public void setText(final String ttext) { + text = ttext; + } + + @ApiModelProperty(required = true, value = "defines the target audience for this motd (one of the following: 'student', 'tutor', 'loggedIn', 'all')") + public String getAudience() { + return audience; + } + + public void setAudience(String a){ + audience = a; + } + + @ApiModelProperty(required = true, value = "when audience equals session, the sessionkey referes to the session the messages belong to") + public String getSessionkey() { + return sessionkey; + } + + public void setSessionkey(String a){ + sessionkey = a; + } + + @ApiModelProperty(required = true, value = "the couchDB ID") + public String get_id() { + return _id; + } + + public void set_id(final String id) { + _id = id; + } + + public void set_rev(final String rev) { + _rev = rev; + } + + public String get_rev() { + return _rev; + } + + @Override + public int hashCode() { + // See http://stackoverflow.com/a/113600 + final int prim = 37; + + int result = 42; + return prim * result + this.motdkey.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !obj.getClass().equals(this.getClass())) { + return false; + } + Motd other = (Motd) obj; + return (this.getMotdkey().equals(other.getMotdkey())); + } +} diff --git a/src/main/java/de/thm/arsnova/entities/MotdList.java b/src/main/java/de/thm/arsnova/entities/MotdList.java new file mode 100644 index 0000000000000000000000000000000000000000..8d6cef1776c2a80122b9d685710ace5d16869a15 --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/MotdList.java @@ -0,0 +1,68 @@ +/* + * This file is part of ARSnova Backend. + * Copyright (C) 2012-2015 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.entities; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * This class represents a list of motdkeys for a user. + */ +@ApiModel(value = "motdlist", description = "the motdlist to save the messages a user has confirmed to be read") +public class MotdList { + + private String motdkeys; + private String username; + private String _id; + private String _rev; + + @ApiModelProperty(required = true, value = "the motdkeylist") + public String getMotdkeys() { + return motdkeys; + } + + public void setMotdkeys(String motds) { + motdkeys = motds; + } + + @ApiModelProperty(required = true, value = "the username") + public String getUsername() { + return username; + } + + public void setUsername(final String u) { + username = u; + } + + @ApiModelProperty(required = true, value = "the couchDB ID") + public String get_id() { + return _id; + } + + public void set_id(final String id) { + _id = id; + } + + public void set_rev(final String rev) { + _rev = rev; + } + + public String get_rev() { + return _rev; + } +} diff --git a/src/main/java/de/thm/arsnova/entities/User.java b/src/main/java/de/thm/arsnova/entities/User.java index f7bf65ad804d8c79f7db05135c169aef2e780a25..df8f0b7aad809b459134eb4ecfe359a319188f44 100644 --- a/src/main/java/de/thm/arsnova/entities/User.java +++ b/src/main/java/de/thm/arsnova/entities/User.java @@ -45,6 +45,7 @@ public class User implements Serializable { private String username; private String type; private UserSessionService.Role role; + private boolean isAdmin; public User(Google2Profile profile) { setUsername(profile.getEmail()); @@ -104,6 +105,14 @@ public class User implements Serializable { return this.role == role; } + public void setAdmin(boolean a) { + this.isAdmin = a; + } + + public boolean isAdmin() { + return this.isAdmin; + } + @Override public String toString() { return "User [username=" + username + ", type=" + type + "]"; diff --git a/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java b/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java index 488f890cc838ed4e653d130d39a1fb8a8acc86c5..b8b2a69f8ab13e1c6ad3c8eaae1f67c0fea125e7 100644 --- a/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java +++ b/src/main/java/de/thm/arsnova/security/ApplicationPermissionEvaluator.java @@ -19,9 +19,14 @@ package de.thm.arsnova.security; import java.io.Serializable; +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.scribe.up.profile.facebook.FacebookProfile; import org.scribe.up.profile.google.Google2Profile; import org.scribe.up.profile.twitter.TwitterProfile; +import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.authentication.AnonymousAuthenticationToken; @@ -41,6 +46,11 @@ import de.thm.arsnova.exceptions.UnauthorizedException; */ public class ApplicationPermissionEvaluator implements PermissionEvaluator { + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationPermissionEvaluator.class); + + @Value("${security.adminaccount}") + private String adminaccount; + @Autowired private IDatabaseDao dao; @@ -84,6 +94,15 @@ public class ApplicationPermissionEvaluator implements PermissionEvaluator { && checkInterposedQuestionPermission(username, targetId, permission) ) { return true; + } else if ( + /*TODO only account from own database*/ + "motd".equals(targetType) + && permission.equals("admin") + ) { + String[] splittedNames = adminaccount.split(","); + if (Arrays.asList(splittedNames).contains(username)) { + return true; + } } return false; } diff --git a/src/main/java/de/thm/arsnova/services/IMotdService.java b/src/main/java/de/thm/arsnova/services/IMotdService.java new file mode 100644 index 0000000000000000000000000000000000000000..d444a3adaa332047ec267316284ca7580da6b47c --- /dev/null +++ b/src/main/java/de/thm/arsnova/services/IMotdService.java @@ -0,0 +1,61 @@ +/* + * This file is part of ARSnova Backend. + * Copyright (C) 2012-2015 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.services; + +import java.util.List; +import java.util.Date; +import java.util.Map; +import java.util.Set; + +import de.thm.arsnova.entities.Motd; +import de.thm.arsnova.entities.MotdList; + +/** + * The functionality the motd service should provide. + */ +public interface IMotdService { + Motd getMotd(String keyword); + + List<Motd> getAdminMotds(); //all w/o the sessionmotds + + List<Motd> getAllSessionMotds(final String sessionkey); + + List<Motd> getCurrentMotds(final Date clientdate, final String audience, final String sessionkey); + + List<Motd> filterMotdsByDate(List<Motd> list, Date clientdate); + + List<Motd> filterMotdsByList(List<Motd> list, MotdList motdList); + + void deleteMotd(Motd motd); + + void deleteSessionMotd(final String sessionkey, Motd motd); + + Motd saveMotd(Motd motd); + + Motd saveSessionMotd(final String sessionkey, final Motd motd); + + Motd updateMotd(Motd motd); + + Motd updateSessionMotd(final String sessionkey, Motd motd); + + MotdList getMotdListForUser(final String username); + + MotdList saveUserMotdList(MotdList motdList); + + MotdList updateUserMotdList(MotdList userMotdList); +} diff --git a/src/main/java/de/thm/arsnova/services/MotdService.java b/src/main/java/de/thm/arsnova/services/MotdService.java new file mode 100644 index 0000000000000000000000000000000000000000..8218af881430443eaf4a576b373385d2580c791b --- /dev/null +++ b/src/main/java/de/thm/arsnova/services/MotdService.java @@ -0,0 +1,193 @@ +/* + * This file is part of ARSnova Backend. + * Copyright (C) 2012-2015 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.services; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Date; +import java.util.Set; +import java.util.HashSet; +import java.util.StringTokenizer; + +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.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; + +import de.thm.arsnova.dao.IDatabaseDao; +import de.thm.arsnova.entities.User; +import de.thm.arsnova.entities.Motd; +import de.thm.arsnova.entities.MotdList; +import de.thm.arsnova.exceptions.BadRequestException; +import de.thm.arsnova.exceptions.ForbiddenException; +import de.thm.arsnova.exceptions.NotFoundException; +import de.thm.arsnova.exceptions.PayloadTooLargeException; +import de.thm.arsnova.exceptions.UnauthorizedException; +/** + * Performs all question, interposed question, and answer related operations. + */ +@Service +public class MotdService implements IMotdService { + + @Autowired + private IDatabaseDao databaseDao; + + @Autowired + private IUserService userService; + + private static final Logger LOGGER = LoggerFactory.getLogger(QuestionService.class); + + public void setDatabaseDao(final IDatabaseDao databaseDao) { + this.databaseDao = databaseDao; + } + + @Override + @PreAuthorize("isAuthenticated()") + public Motd getMotd(final String key) { + return databaseDao.getMotdByKey(key); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(1,'motd','admin')") + public List<Motd> getAdminMotds() { + return databaseDao.getAdminMotds(); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')") + public List<Motd> getAllSessionMotds(final String sessionkey) { + return databaseDao.getMotdsForSession(sessionkey); + } + + @Override + public List<Motd> getCurrentMotds(final Date clientdate, final String audience, final String sessionkey) { + List<Motd> motds = new ArrayList<Motd>(); + switch (audience) { + case "all": motds = databaseDao.getMotdsForAll(); break; + case "loggedIn": motds = databaseDao.getMotdsForLoggedIn(); break; + case "students": motds = databaseDao.getMotdsForStudents(); break; + case "tutors": motds = databaseDao.getMotdsForTutors(); break; + case "session": motds = databaseDao.getMotdsForSession(sessionkey); break; + default: motds = databaseDao.getMotdsForAll(); break; + } + return filterMotdsByDate(motds, clientdate); + } + + @Override + public List<Motd> filterMotdsByDate(List<Motd> list, Date clientdate) { + List<Motd> returns = new ArrayList<Motd>(); + for (Motd motd : list) { + if (motd.getStartdate().before(clientdate) && motd.getEnddate().after(clientdate)) { + returns.add(motd); + } + } + return returns; + } + + @Override + public List<Motd> filterMotdsByList(List<Motd> list, MotdList motdlist) { + if (motdlist != null && motdlist.getMotdkeys() != null && !motdlist.getMotdkeys().isEmpty()) { + List<Motd> returns = new ArrayList<Motd>(); + HashSet<String> keys = new HashSet(500); // Or a more realistic size + StringTokenizer st = new StringTokenizer(motdlist.getMotdkeys(), ","); + while(st.hasMoreTokens()) + keys.add(st.nextToken()); + for (Motd motd : list) { + if (!keys.contains(motd.getMotdkey())) { + returns.add(motd); + } + } + return returns; + } + else { + return list; + } + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(1,'motd','admin')") + public Motd saveMotd(final Motd motd) { + return databaseDao.createOrUpdateMotd(motd); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')") + public Motd saveSessionMotd(final String sessionkey, final Motd motd) { + return databaseDao.createOrUpdateMotd(motd); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(1,'motd','admin')") + public Motd updateMotd(final Motd motd) { + return databaseDao.createOrUpdateMotd(motd); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')") + public Motd updateSessionMotd(final String sessionkey, final Motd motd) { + return databaseDao.createOrUpdateMotd(motd); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(1,'motd','admin')") + public void deleteMotd(Motd motd) { + databaseDao.deleteMotd(motd); + } + + @Override + @PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')") + public void deleteSessionMotd(final String sessionkey, Motd motd) { + databaseDao.deleteMotd(motd); + } + + @Override + @PreAuthorize("isAuthenticated()") + public MotdList getMotdListForUser(final String username) { + final User user = userService.getCurrentUser(); + if (username.equals(user.getUsername()) && !user.getType().equals("guest")) { + return databaseDao.getMotdListForUser(username); + } + return null; + } + + @Override + @PreAuthorize("isAuthenticated()") + public MotdList saveUserMotdList(MotdList motdList) { + final User user = userService.getCurrentUser(); + if (user.getUsername().equals(motdList.getUsername())) { + return databaseDao.createOrUpdateMotdList(motdList); + } + return null; + } + + @Override + @PreAuthorize("isAuthenticated()") + public MotdList updateUserMotdList(MotdList motdList) { + final User user = userService.getCurrentUser(); + if (user.getUsername().equals(motdList.getUsername())) { + return databaseDao.createOrUpdateMotdList(motdList); + } + return null; + } +} diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java index 7fba2f8ae692847dc865f325051409bf63260128..803206a8e72f393e874b81858600539469c9c016 100644 --- a/src/main/java/de/thm/arsnova/services/UserService.java +++ b/src/main/java/de/thm/arsnova/services/UserService.java @@ -134,6 +134,9 @@ public class UserService implements IUserService { @Value("${security.authentication.login-try-limit}") private int loginTryLimit; + @Value("${security.adminaccount}") + private String adminaccount; + private Pattern mailPattern; private BytesKeyGenerator keygen; private BCryptPasswordEncoder encoder; @@ -188,6 +191,9 @@ public class UserService implements IUserService { } } + String[] splittedNames = adminaccount.split(","); + user.setAdmin(Arrays.asList(splittedNames).contains(user.getUsername())); + if (user == null || user.getUsername().equals("anonymous")) { throw new UnauthorizedException(); } diff --git a/src/main/resources/arsnova.properties.example b/src/main/resources/arsnova.properties.example index 0ddea5c1fb9455083d8165d07e93b7cb7746bfeb..f84a81bdf538d4a79ddb176a463d6fdac962c398 100644 --- a/src/main/resources/arsnova.properties.example +++ b/src/main/resources/arsnova.properties.example @@ -24,6 +24,9 @@ security.storepass=arsnova socketio.ip=0.0.0.0 socketio.port=10443 +# admin account +security.adminaccount= + ################################################################################ # Database diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index 99952d3583cb0a3c392bc807f5d3ddddd7775659..6a5e369cf4549771ed9da4d53cc1d982cc129478 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -37,6 +37,8 @@ import de.thm.arsnova.entities.SessionInfo; import de.thm.arsnova.entities.SortOrder; import de.thm.arsnova.entities.Statistics; import de.thm.arsnova.entities.User; +import de.thm.arsnova.entities.Motd; +import de.thm.arsnova.entities.MotdList; import de.thm.arsnova.entities.transport.ImportExportSession; import de.thm.arsnova.exceptions.NoContentException; import de.thm.arsnova.exceptions.NotFoundException; @@ -648,4 +650,74 @@ public class StubDatabaseDao implements IDatabaseDao { // TODO Auto-generated method stub return null; } + + @Override + public List<Motd> getAdminMotds() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<Motd> getMotdsForAll() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<Motd> getMotdsForLoggedIn() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<Motd> getMotdsForTutors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<Motd> getMotdsForStudents() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<Motd> getMotdsForSession(final String sessionkey) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<Motd> getMotds(NovaView view) { + return null; + } + + @Override + public Motd getMotdByKey(String key) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Motd createOrUpdateMotd(Motd motd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void deleteMotd(Motd motd) { + // TODO Auto-generated method stub + } + + @Override + public MotdList getMotdListForUser(final String username) { + // TODO Auto-generated method stub + return null; + } + + @Override + public MotdList createOrUpdateMotdList(MotdList motdlist) { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/test/resources/arsnova.properties.example b/src/test/resources/arsnova.properties.example index 0ddea5c1fb9455083d8165d07e93b7cb7746bfeb..5c418583d93828e765366b48816946f7d28728d7 100644 --- a/src/test/resources/arsnova.properties.example +++ b/src/test/resources/arsnova.properties.example @@ -24,6 +24,8 @@ security.storepass=arsnova socketio.ip=0.0.0.0 socketio.port=10443 +# admin account +security.adminaccount=username ################################################################################ # Database