Skip to content
Snippets Groups Projects
Commit 37d6159e authored by Daniel Gerhardt's avatar Daniel Gerhardt
Browse files

Fix Comments for /v2

parent d5c5ce29
No related merge requests found
...@@ -18,13 +18,14 @@ ...@@ -18,13 +18,14 @@
package de.thm.arsnova.controller.v2; package de.thm.arsnova.controller.v2;
import de.thm.arsnova.controller.PaginationController; import de.thm.arsnova.controller.PaginationController;
import de.thm.arsnova.entities.UserProfile; import de.thm.arsnova.entities.Room;
import de.thm.arsnova.entities.migration.FromV2Migrator; import de.thm.arsnova.entities.migration.FromV2Migrator;
import de.thm.arsnova.entities.migration.ToV2Migrator; import de.thm.arsnova.entities.migration.ToV2Migrator;
import de.thm.arsnova.entities.migration.v2.Comment; import de.thm.arsnova.entities.migration.v2.Comment;
import de.thm.arsnova.entities.migration.v2.CommentReadingCount; import de.thm.arsnova.entities.migration.v2.CommentReadingCount;
import de.thm.arsnova.exceptions.BadRequestException; import de.thm.arsnova.exceptions.BadRequestException;
import de.thm.arsnova.services.CommentService; import de.thm.arsnova.services.CommentService;
import de.thm.arsnova.services.RoomService;
import de.thm.arsnova.services.UserService; import de.thm.arsnova.services.UserService;
import de.thm.arsnova.web.DeprecatedApi; import de.thm.arsnova.web.DeprecatedApi;
import de.thm.arsnova.web.Pagination; import de.thm.arsnova.web.Pagination;
...@@ -44,6 +45,7 @@ import org.springframework.web.bind.annotation.RequestParam; ...@@ -44,6 +45,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -58,6 +60,9 @@ public class CommentController extends PaginationController { ...@@ -58,6 +60,9 @@ public class CommentController extends PaginationController {
@Autowired @Autowired
private CommentService commentService; private CommentService commentService;
@Autowired
private RoomService roomService;
@Autowired @Autowired
private UserService userService; private UserService userService;
...@@ -97,7 +102,7 @@ public class CommentController extends PaginationController { ...@@ -97,7 +102,7 @@ public class CommentController extends PaginationController {
@ApiOperation(value = "Retrieves an Comment", @ApiOperation(value = "Retrieves an Comment",
nickname = "getComment") nickname = "getComment")
@RequestMapping(value = "/{commentId}", method = RequestMethod.GET) @RequestMapping(value = "/{commentId}", method = RequestMethod.GET)
public Comment getComment(@ApiParam(value = "ID of the Comment that needs to be deleted", required = true) @PathVariable final String commentId) { public Comment getComment(@ApiParam(value = "ID of the Comment that needs to be deleted", required = true) @PathVariable final String commentId) throws IOException {
return toV2Migrator.migrate(commentService.getAndMarkRead(commentId)); return toV2Migrator.migrate(commentService.getAndMarkRead(commentId));
} }
...@@ -112,8 +117,10 @@ public class CommentController extends PaginationController { ...@@ -112,8 +117,10 @@ public class CommentController extends PaginationController {
@ApiParam(value = "Room-Key from current room", required = true) @RequestParam("sessionkey") final String roomShortId, @ApiParam(value = "Room-Key from current room", required = true) @RequestParam("sessionkey") final String roomShortId,
@ApiParam(value = "the body from the new comment", required = true) @RequestBody final Comment comment @ApiParam(value = "the body from the new comment", required = true) @RequestBody final Comment comment
) { ) {
UserProfile profile = userService.getByUsername(comment.getCreator()); de.thm.arsnova.entities.Comment commentV3 = fromV2Migrator.migrate(comment);
if (commentService.save(fromV2Migrator.migrate(comment, profile))) { Room roomV3 = roomService.getByShortId(roomShortId);
commentV3.setRoomId(roomV3.getId());
if (commentService.save(commentV3)) {
return; return;
} }
......
...@@ -22,6 +22,7 @@ import de.thm.arsnova.entities.ChoiceQuestionContent; ...@@ -22,6 +22,7 @@ import de.thm.arsnova.entities.ChoiceQuestionContent;
import de.thm.arsnova.entities.TextAnswer; import de.thm.arsnova.entities.TextAnswer;
import de.thm.arsnova.entities.UserProfile; import de.thm.arsnova.entities.UserProfile;
import de.thm.arsnova.entities.migration.v2.*; import de.thm.arsnova.entities.migration.v2.*;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -221,14 +222,17 @@ public class FromV2Migrator { ...@@ -221,14 +222,17 @@ public class FromV2Migrator {
return to; return to;
} }
public de.thm.arsnova.entities.Comment migrate(final Comment from, final UserProfile creator) { public de.thm.arsnova.entities.Comment migrate(final Comment from, @Nullable final UserProfile creator) {
if (!creator.getLoginId().equals(from.getCreator())) { if (creator == null && from.getCreator() != null ||
creator != null && !creator.getLoginId().equals(from.getCreator())) {
throw new IllegalArgumentException("Username of creator object does not match comment creator."); throw new IllegalArgumentException("Username of creator object does not match comment creator.");
} }
final de.thm.arsnova.entities.Comment to = new de.thm.arsnova.entities.Comment(); final de.thm.arsnova.entities.Comment to = new de.thm.arsnova.entities.Comment();
copyCommonProperties(from, to); copyCommonProperties(from, to);
to.setRoomId(from.getSessionId()); to.setRoomId(from.getSessionId());
to.setCreatorId(creator.getId()); if (creator != null) {
to.setCreatorId(creator.getId());
}
to.setSubject(from.getSubject()); to.setSubject(from.getSubject());
to.setBody(from.getText()); to.setBody(from.getText());
to.setTimestamp(new Date(from.getTimestamp())); to.setTimestamp(new Date(from.getTimestamp()));
...@@ -237,6 +241,11 @@ public class FromV2Migrator { ...@@ -237,6 +241,11 @@ public class FromV2Migrator {
return to; return to;
} }
public de.thm.arsnova.entities.Comment migrate(final Comment from) {
return migrate(from, null);
}
public de.thm.arsnova.entities.Motd migrate(final Motd from) { public de.thm.arsnova.entities.Motd migrate(final Motd from) {
final de.thm.arsnova.entities.Motd to = new de.thm.arsnova.entities.Motd(); final de.thm.arsnova.entities.Motd to = new de.thm.arsnova.entities.Motd();
copyCommonProperties(from, to); copyCommonProperties(from, to);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
package de.thm.arsnova.entities.migration.v2; package de.thm.arsnova.entities.migration.v2;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.annotation.JsonView;
import de.thm.arsnova.entities.UserAuthentication; import de.thm.arsnova.entities.UserAuthentication;
import de.thm.arsnova.entities.serialization.View; import de.thm.arsnova.entities.serialization.View;
...@@ -43,6 +44,7 @@ public class Comment implements Entity { ...@@ -43,6 +44,7 @@ public class Comment implements Entity {
private String creator; private String creator;
@JsonView({View.Persistence.class, View.Public.class}) @JsonView({View.Persistence.class, View.Public.class})
@JsonProperty("_id")
public String getId() { public String getId() {
return id; return id;
} }
...@@ -62,6 +64,13 @@ public class Comment implements Entity { ...@@ -62,6 +64,13 @@ public class Comment implements Entity {
return rev; return rev;
} }
/* Need because of an inconsistency in the v2 API */
@JsonView(View.Public.class)
@JsonProperty("id")
public String getApiId() {
return id;
}
@ApiModelProperty(required = true, value = "is read") @ApiModelProperty(required = true, value = "is read")
@JsonView({View.Persistence.class, View.Public.class}) @JsonView({View.Persistence.class, View.Public.class})
public boolean isRead() { public boolean isRead() {
......
...@@ -52,8 +52,8 @@ public class CouchDbCommentRepository extends CouchDbCrudRepository<Comment> imp ...@@ -52,8 +52,8 @@ public class CouchDbCommentRepository extends CouchDbCrudRepository<Comment> imp
@Override @Override
public CommentReadingCount countReadingByRoomIdAndUser(final String roomId, final UserAuthentication user) { public CommentReadingCount countReadingByRoomIdAndUser(final String roomId, final UserAuthentication user) {
final ViewResult result = db.queryView(createQuery("by_roomid_creatorid_read") final ViewResult result = db.queryView(createQuery("by_roomid_creatorid_read")
.startKey(ComplexKey.of(roomId, user.getUsername())) .startKey(ComplexKey.of(roomId, user.getId()))
.endKey(ComplexKey.of(roomId, user.getUsername(), ComplexKey.emptyObject())) .endKey(ComplexKey.of(roomId, user.getId(), ComplexKey.emptyObject()))
.reduce(true) .reduce(true)
.group(true)); .group(true));
return calculateReadingCount(result); return calculateReadingCount(result);
......
package de.thm.arsnova.services; package de.thm.arsnova.services;
import de.thm.arsnova.entities.Comment; import de.thm.arsnova.entities.Comment;
import de.thm.arsnova.entities.UserAuthentication;
import de.thm.arsnova.entities.migration.v2.CommentReadingCount; import de.thm.arsnova.entities.migration.v2.CommentReadingCount;
import java.io.IOException;
import java.util.List; import java.util.List;
public interface CommentService extends EntityService<Comment> { public interface CommentService extends EntityService<Comment> {
...@@ -15,9 +15,7 @@ public interface CommentService extends EntityService<Comment> { ...@@ -15,9 +15,7 @@ public interface CommentService extends EntityService<Comment> {
List<Comment> getByRoomShortId(String roomShortId, int offset, int limit); List<Comment> getByRoomShortId(String roomShortId, int offset, int limit);
Comment getAndMarkRead(String commentId); Comment getAndMarkRead(String commentId) throws IOException;
Comment getAndMarkReadInternal(String commentId, UserAuthentication user);
void delete(String commentId); void delete(String commentId);
......
...@@ -18,8 +18,11 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert ...@@ -18,8 +18,11 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Performs all comment related operations. * Performs all comment related operations.
...@@ -53,9 +56,8 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem ...@@ -53,9 +56,8 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem
@Override @Override
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
public boolean save(final Comment comment) { public boolean save(final Comment comment) {
final Room room = roomRepository.findByShortId(comment.getRoomId()); final Room room = roomRepository.findOne(comment.getRoomId());
final UserAuthentication user = userService.getCurrentUser(); final UserAuthentication user = userService.getCurrentUser();
comment.setRoomId(room.getId());
comment.setCreatorId(user.getId()); comment.setCreatorId(user.getId());
comment.setRead(false); comment.setRead(false);
if (comment.getTimestamp() == null) { if (comment.getTimestamp() == null) {
...@@ -138,30 +140,16 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem ...@@ -138,30 +140,16 @@ public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implem
} }
@Override @Override
@PreAuthorize("isAuthenticated()") @PreAuthorize("hasPermission(#commentId, 'comment', 'update')")
public Comment getAndMarkRead(final String commentId) { public Comment getAndMarkRead(final String commentId) throws IOException {
final UserAuthentication user = userService.getCurrentUser();
return this.getAndMarkReadInternal(commentId, user);
}
/*
* The "internal" suffix means it is called by internal services that have no authentication!
* TODO: Find a better way of doing this...
*/
@Override
public Comment getAndMarkReadInternal(final String commentId, UserAuthentication user) {
final Comment comment = commentRepository.findOne(commentId); final Comment comment = commentRepository.findOne(commentId);
if (comment == null) { if (comment == null) {
throw new NotFoundException(); throw new NotFoundException();
} }
final Room room = roomRepository.findOne(comment.getRoomId()); Map<String, Object> changes = new HashMap<>();
if (!comment.getCreatorId().equals(user.getId()) && !room.getOwnerId().equals(user.getId())) { changes.put("read", true);
throw new UnauthorizedException(); patch(comment, changes);
}
if (room.getOwnerId().equals(user.getId())) {
comment.setRead(true);
save(comment);
}
return comment; return comment;
} }
......
...@@ -53,6 +53,7 @@ import org.springframework.stereotype.Component; ...@@ -53,6 +53,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
...@@ -196,8 +197,8 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer, Arsnova ...@@ -196,8 +197,8 @@ public class ArsnovaSocketioServerImpl implements ArsnovaSocketioServer, Arsnova
AckRequest ackRequest) { AckRequest ackRequest) {
final UserAuthentication user = userService.getUserToSocketId(client.getSessionId()); final UserAuthentication user = userService.getUserToSocketId(client.getSessionId());
try { try {
commentService.getAndMarkReadInternal(comment.getId(), user); commentService.getAndMarkRead(comment.getId());
} catch (NotFoundException | UnauthorizedException e) { } catch (IOException | NotFoundException | UnauthorizedException e) {
logger.error("Loading of comment {} failed for user {} with exception {}", comment.getId(), user, e.getMessage()); logger.error("Loading of comment {} failed for user {} with exception {}", comment.getId(), user, e.getMessage());
} }
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment