improvements + bookmarks

This commit is contained in:
_Bastler 2021-10-04 13:02:40 +02:00
parent 1fc18fdeb2
commit d3f6c86db6
48 changed files with 1542 additions and 432 deletions

View File

@ -8,15 +8,15 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/** /**
* * The Class Application.
* @author spring-cachet-monitoring@champonthis.de
*
*/ */
@SpringBootApplication @SpringBootApplication
public class Application extends SpringBootServletInitializer { public class Application extends SpringBootServletInitializer {
/** /**
* @param args * The main method.
*
* @param args the arguments
*/ */
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(Application.class, args); SpringApplication.run(Application.class, args);

View File

@ -13,8 +13,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
/** /**
* @author monitoring@bstly.de * The Class JPAConfig.
*
*/ */
@Configuration @Configuration
@EnableJpaAuditing() @EnableJpaAuditing()
@ -23,6 +22,11 @@ public class JPAConfig {
@Autowired @Autowired
private EntityManager em; private EntityManager em;
/**
* Jpa query factory.
*
* @return the JPA query factory
*/
@Bean @Bean
public JPAQueryFactory jpaQueryFactory() { public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(em); return new JPAQueryFactory(em);

View File

@ -12,17 +12,22 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.context.support.ReloadableResourceBundleMessageSource;
/** /**
* @author monitoring@bstly.de * The Class MessageSourceConfig.
*
*/ */
@Configuration @Configuration
public class MessageSourceConfig { public class MessageSourceConfig {
@Value("${bstly.board.title:bstlboard}") @Value("${bstly.board.title:bstlboard}")
private String title; private String title;
@Value("${bstly.board.url:http://localhost:8080}") @Value("${bstly.board.url:http://localhost:8080}")
private String baseUrl; private String baseUrl;
/**
* Message source.
*
* @return the message source
*/
@Bean @Bean
public MessageSource messageSource() { public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();

View File

@ -0,0 +1,97 @@
/**
*
*/
package de.bstly.board.businesslogic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.google.common.collect.Lists;
import de.bstly.board.model.Bookmarks;
import de.bstly.board.model.QBookmarks;
import de.bstly.board.repository.BookmarksRepository;
import de.bstly.board.repository.EntryRepository;
import de.bstly.board.repository.LocalUserRepository;
/**
* The Class BookmarksManager.
*/
@Component
public class BookmarksManager {
@Autowired
private BookmarksRepository bookmarksRepository;
@Autowired
private EntryRepository entryRepository;
@Autowired
private LocalUserRepository localUserRepository;
private QBookmarks qBookmarks = QBookmarks.bookmarks;
/**
* Gets the.
*
* @param username the username
* @return the bookmarks
*/
public Bookmarks get(String username) {
return bookmarksRepository.findById(username).orElse(new Bookmarks(username));
}
/**
* Checks for entry.
*
* @param username the username
* @param entryId the entry id
* @return true, if successful
*/
public boolean hasEntry(String username, Long entryId) {
return bookmarksRepository
.exists(qBookmarks.username.eq(username).and(qBookmarks.entries.contains(entryId)));
}
/**
* Adds the entry.
*
* @param username the username
* @param entryId the entry id
*/
public void addEntry(String username, Long entryId) {
Assert.isTrue(entryRepository.existsById(entryId), "Invalid entryid");
Assert.isTrue(localUserRepository.existsById(username), "Invalid username");
Bookmarks bookmarks = get(username);
if (bookmarks.getEntries() == null) {
bookmarks.setEntries(Lists.newArrayList());
}
if (!hasEntry(username, entryId)) {
bookmarks.getEntries().add(entryId);
bookmarksRepository.save(bookmarks);
}
}
/**
* Removes the entry.
*
* @param username the username
* @param entryId the entry id
*/
public void removeEntry(String username, Long entryId) {
Assert.isTrue(entryRepository.existsById(entryId), "Invalid entryid");
Assert.isTrue(localUserRepository.existsById(username), "Invalid username");
Bookmarks bookmarks = get(username);
if (bookmarks.getEntries() == null) {
bookmarks.setEntries(Lists.newArrayList());
}
if (hasEntry(username, entryId)) {
bookmarks.getEntries().remove(entryId);
bookmarksRepository.save(bookmarks);
}
}
}

View File

@ -22,28 +22,34 @@ import de.bstly.board.repository.CommentRepository;
import de.bstly.board.repository.VoteRepository; import de.bstly.board.repository.VoteRepository;
/** /**
* @author Lurkars * The Class CommentManager.
*
*/ */
@Component @Component
public class CommentManager { public class CommentManager {
@Autowired @Autowired
private CommentRepository commentRepository; private CommentRepository commentRepository;
@Autowired @Autowired
private VoteRepository voteRepository; private VoteRepository voteRepository;
@Autowired @Autowired
private VoteManager voteManager; private VoteManager voteManager;
private QComment qComment = QComment.comment; private QComment qComment = QComment.comment;
private QVote qVote = QVote.vote; private QVote qVote = QVote.vote;
/** /**
* * Fetch by ranking.
* @param parent *
* @param target * @param target the target
* @param page * @param parent the parent
* @param size * @param date the date
* @return * @param gravity the gravity
* @param page the page
* @param size the size
* @return the page
*/ */
public Page<Comment> fetchByRanking(Long target, Long parent, Instant date, double gravity, public Page<Comment> fetchByRanking(Long target, Long parent, Instant date, double gravity,
@ -58,11 +64,14 @@ public class CommentManager {
} }
/** /**
* * Fetch by date.
* @param page *
* @param size * @param target the target
* @param order * @param parent the parent
* @return * @param date the date
* @param page the page
* @param size the size
* @return the page
*/ */
public Page<Comment> fetchByDate(Long target, Long parent, Instant date, int page, int size) { public Page<Comment> fetchByDate(Long target, Long parent, Instant date, int page, int size) {
if (parent == null) { if (parent == null) {
@ -79,10 +88,11 @@ public class CommentManager {
} }
/** /**
* * Count.
* @param target *
* @param parent * @param target the target
* @return * @param parent the parent
* @return the long
*/ */
public Long count(Long target, Long parent) { public Long count(Long target, Long parent) {
if (parent == null) { if (parent == null) {
@ -93,18 +103,20 @@ public class CommentManager {
} }
/** /**
* * Count.
* @param target *
* @return * @param target the target
* @return the long
*/ */
public Long count(Long target) { public Long count(Long target) {
return commentRepository.count(qComment.target.eq(target)); return commentRepository.count(qComment.target.eq(target));
} }
/** /**
* * Apply metadata.
* @param username *
* @param comment * @param username the username
* @param comment the comment
*/ */
public void applyMetadata(String username, Comment comment) { public void applyMetadata(String username, Comment comment) {
if (!comment.getMetadata().containsKey("comments")) { if (!comment.getMetadata().containsKey("comments")) {
@ -114,21 +126,21 @@ public class CommentManager {
comment.getMetadata().put("points", comment.getMetadata().put("points",
voteManager.getPoints(comment.getId(), Types.comment)); voteManager.getPoints(comment.getId(), Types.comment));
} }
if (!comment.getMetadata().containsKey("upvoted")) { if (!comment.getMetadata().containsKey("upvoted")) {
comment.getMetadata().put("upvoted", comment.getMetadata().put("upvoted",
voteRepository.exists(qVote.target.eq(comment.getId()) voteRepository.exists(qVote.target.eq(comment.getId())
.and(qVote.targetType.eq(Types.comment)).and(qVote.type.eq(VoteType.up)) .and(qVote.targetType.eq(Types.comment)).and(qVote.type.eq(VoteType.up))
.and(qVote.author.eq(username)))); .and(qVote.author.eq(username))));
} }
if (!comment.getMetadata().containsKey("downvoted")) { if (!comment.getMetadata().containsKey("downvoted")) {
comment.getMetadata().put("downvoted", comment.getMetadata().put("downvoted",
voteRepository.exists(qVote.target.eq(comment.getId()) voteRepository.exists(qVote.target.eq(comment.getId())
.and(qVote.targetType.eq(Types.comment)) .and(qVote.targetType.eq(Types.comment))
.and(qVote.type.eq(VoteType.down)).and(qVote.author.eq(username)))); .and(qVote.type.eq(VoteType.down)).and(qVote.author.eq(username))));
} }
if (!comment.getMetadata().containsKey("unvote")) { if (!comment.getMetadata().containsKey("unvote")) {
comment.getMetadata().put("unvote", comment.getMetadata().put("unvote",
voteRepository.exists( voteRepository.exists(
@ -138,8 +150,10 @@ public class CommentManager {
} }
/** /**
* * Apply metadata.
* @param entries *
* @param username the username
* @param entries the entries
*/ */
public void applyMetadata(String username, List<Comment> entries) { public void applyMetadata(String username, List<Comment> entries) {
for (Comment comment : entries) { for (Comment comment : entries) {
@ -148,33 +162,40 @@ public class CommentManager {
} }
/** /**
* @param id * Exists.
* @return *
* @param id the id
* @return true, if successful
*/ */
public boolean exists(Long id) { public boolean exists(Long id) {
return commentRepository.existsById(id); return commentRepository.existsById(id);
} }
/** /**
* @param id * Gets the.
* @return *
* @param id the id
* @return the comment
*/ */
public Comment get(Long id) { public Comment get(Long id) {
return commentRepository.findById(id).orElse(null); return commentRepository.findById(id).orElse(null);
} }
/** /**
* @param comment * Save.
* @return *
* @param comment the comment
* @return the comment
*/ */
public Comment save(Comment comment) { public Comment save(Comment comment) {
return commentRepository.save(comment); return commentRepository.save(comment);
} }
/** /**
* * Gets the points.
* @param commentId *
* @return * @param commentId the comment id
* @return the points
*/ */
public long getPoints(Long commentId) { public long getPoints(Long commentId) {
long upvotes = voteRepository.count(qVote.targetType.eq(Types.comment) long upvotes = voteRepository.count(qVote.targetType.eq(Types.comment)
@ -185,8 +206,9 @@ public class CommentManager {
} }
/** /**
* * Delete.
* @param comment *
* @param comment the comment
*/ */
public void delete(Comment comment) { public void delete(Comment comment) {
for (Comment subcomment : commentRepository.findAll(qComment.parent.eq(comment.getId()))) { for (Comment subcomment : commentRepository.findAll(qComment.parent.eq(comment.getId()))) {
@ -199,8 +221,9 @@ public class CommentManager {
} }
/** /**
* * Delete by target.
* @param target *
* @param target the target
*/ */
public void deleteByTarget(Long target) { public void deleteByTarget(Long target) {
for (Comment comment : commentRepository.findAll(qComment.target.eq(target))) { for (Comment comment : commentRepository.findAll(qComment.target.eq(target))) {

View File

@ -14,6 +14,9 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order; import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.google.common.collect.Lists;
import de.bstly.board.model.Bookmarks;
import de.bstly.board.model.Entry; import de.bstly.board.model.Entry;
import de.bstly.board.model.QEntry; import de.bstly.board.model.QEntry;
import de.bstly.board.model.QVote; import de.bstly.board.model.QVote;
@ -24,8 +27,7 @@ import de.bstly.board.repository.EntryRepository;
import de.bstly.board.repository.VoteRepository; import de.bstly.board.repository.VoteRepository;
/** /**
* @author Lurkars * The Class EntryManager.
*
*/ */
@Component @Component
public class EntryManager { public class EntryManager {
@ -38,29 +40,39 @@ public class EntryManager {
private VoteManager voteManager; private VoteManager voteManager;
@Autowired @Autowired
private VoteRepository voteRepository; private VoteRepository voteRepository;
@Autowired
private BookmarksManager bookmarksManager;
private QEntry qEntry = QEntry.entry; private QEntry qEntry = QEntry.entry;
private QVote qVote = QVote.vote; private QVote qVote = QVote.vote;
@Value("${bstly.board.ranking.gravity:1.8}") @Value("${bstly.board.ranking.gravity:1.8}")
private double GRAVITY; private double GRAVITY;
/** /**
* * Direct fetch by ranking.
* @param page *
* @param size * @param date the date
* @return * @param gravity the gravity
* @param page the page
* @param size the size
* @return the page
*/ */
public Page<Entry> fetchByRanking(int page, int size) { public Page<RankedEntry> fetchByRanking(Instant date, double gravity, int page,
return entryRepository.findAll( int size) {
PageRequest.of(page, size, Sort.by(Order.desc("ranking"), Order.desc("created")))); return entryRepository.findAllByRanking(date, gravity, PageRequest.of(page, size));
} }
/** /**
* * Fetch by date.
* @param page *
* @param size * @param date the date
* @param order * @param page the page
* @return * @param size the size
* @return the page
*/ */
public Page<Entry> fetchByDate(Instant date, int page, int size) { public Page<Entry> fetchByDate(Instant date, int page, int size) {
return entryRepository.findAll(qEntry.created.before(date), return entryRepository.findAll(qEntry.created.before(date),
@ -68,53 +80,69 @@ public class EntryManager {
} }
/** /**
* * Gets the entries.
* @param page *
* @param size * @param username the username
* @return * @param page the page
* @param size the size
* @return the entries
*/ */
public Page<RankedEntry> directFetchByRanking(Instant date, double gravity, int page, public Page<Entry> fetchByBookmarks(String username, int page, int size) {
int size) { Bookmarks bookmarks = bookmarksManager.get(username);
return entryRepository.findAllByRanking(date, gravity, PageRequest.of(page, size));
if (bookmarks.getEntries() == null) {
bookmarks.setEntries(Lists.newArrayList());
}
return entryRepository.findAll(qEntry.id.in(bookmarks.getEntries()),
PageRequest.of(page, size, Sort.by(Order.desc("created"))));
} }
/** /**
* * Apply metadata.
* @param entry *
* @param username the username
* @param entry the entry
*/ */
public void applyMetadata(String username, Entry entry) { public void applyMetadata(String username, Entry entry) {
if (!entry.getMetadata().containsKey("comments")) { if (!entry.getMetadata().containsKey("comments")) {
entry.getMetadata().put("comments", commentManager.count(entry.getId())); entry.getMetadata().put("comments", commentManager.count(entry.getId()));
} }
if (!entry.getMetadata().containsKey("points")) { if (!entry.getMetadata().containsKey("points")) {
entry.getMetadata().put("points", voteManager.getPoints(entry.getId(), Types.entry)); entry.getMetadata().put("points", voteManager.getPoints(entry.getId(), Types.entry));
} }
if (!entry.getMetadata().containsKey("bookmarked")) {
entry.getMetadata().put("bookmarked",
bookmarksManager.hasEntry(username, entry.getId()));
}
if (!entry.getMetadata().containsKey("upvoted")) { if (!entry.getMetadata().containsKey("upvoted")) {
entry.getMetadata().put("upvoted", entry.getMetadata().put("upvoted",
voteRepository.exists(qVote.target.eq(entry.getId()) voteRepository.exists(qVote.target.eq(entry.getId())
.and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.up)) .and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.up))
.and(qVote.author.eq(username)))); .and(qVote.author.eq(username))));
} }
if (!entry.getMetadata().containsKey("downvoted")) { if (!entry.getMetadata().containsKey("downvoted")) {
entry.getMetadata().put("downvoted", entry.getMetadata().put("downvoted",
voteRepository.exists(qVote.target.eq(entry.getId()) voteRepository.exists(qVote.target.eq(entry.getId())
.and(qVote.targetType.eq(Types.entry)) .and(qVote.targetType.eq(Types.entry)).and(qVote.type.eq(VoteType.down))
.and(qVote.type.eq(VoteType.down)).and(qVote.author.eq(username)))); .and(qVote.author.eq(username))));
} }
if (!entry.getMetadata().containsKey("unvote")) { if (!entry.getMetadata().containsKey("unvote")) {
entry.getMetadata().put("unvote", entry.getMetadata().put("unvote", voteRepository.exists(qVote.target.eq(entry.getId())
voteRepository.exists( .and(qVote.targetType.eq(Types.entry)).and(qVote.author.eq(username))));
qVote.target.eq(entry.getId()).and(qVote.targetType.eq(Types.entry))
.and(qVote.author.eq(username))));
} }
} }
/** /**
* * Apply metadata.
* @param entries *
* @param username the username
* @param entries the entries
*/ */
public void applyMetadata(String username, List<Entry> entries) { public void applyMetadata(String username, List<Entry> entries) {
for (Entry entry : entries) { for (Entry entry : entries) {
@ -123,32 +151,39 @@ public class EntryManager {
} }
/** /**
* @param id * Exists.
* @return *
* @param id the id
* @return true, if successful
*/ */
public boolean exists(Long id) { public boolean exists(Long id) {
return entryRepository.existsById(id); return entryRepository.existsById(id);
} }
/** /**
* @param id * Gets the.
* @return *
* @param id the id
* @return the entry
*/ */
public Entry get(Long id) { public Entry get(Long id) {
return entryRepository.findById(id).orElse(null); return entryRepository.findById(id).orElse(null);
} }
/** /**
* @param entry * Save.
* @return *
* @param entry the entry
* @return the entry
*/ */
public Entry save(Entry entry) { public Entry save(Entry entry) {
return entryRepository.save(entry); return entryRepository.save(entry);
} }
/** /**
* * Delete.
* @param entry *
* @param entry the entry
*/ */
public void delete(Entry entry) { public void delete(Entry entry) {
commentManager.deleteByTarget(entry.getId()); commentManager.deleteByTarget(entry.getId());
@ -157,9 +192,10 @@ public class EntryManager {
} }
/** /**
* * Gets the points.
* @param entryId *
* @return * @param entryId the entry id
* @return the points
*/ */
public long getPoints(Long entryId) { public long getPoints(Long entryId) {
long upvotes = voteRepository.count(qVote.targetType.eq(Types.entry) long upvotes = voteRepository.count(qVote.targetType.eq(Types.entry)

View File

@ -12,48 +12,51 @@ import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit; import java.time.temporal.TemporalUnit;
/** /**
* @author _bastler@bstly.de * The Class InstantHelper.
*
*/ */
public class InstantHelper { public class InstantHelper {
/** /**
* * Plus.
* @param instant *
* @param amount * @param instant the instant
* @return * @param amount the amount
* @return the instant
*/ */
public static Instant plus(Instant instant, TemporalAmount amount) { public static Instant plus(Instant instant, TemporalAmount amount) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant(); return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant();
} }
/** /**
* * Plus.
* @param instant *
* @param amountToAdd * @param instant the instant
* @param unit * @param amountToAdd the amount to add
* @return * @param unit the unit
* @return the instant
*/ */
public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) { public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant(); return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant();
} }
/** /**
* * Minus.
* @param instant *
* @param amount * @param instant the instant
* @return * @param amount the amount
* @return the instant
*/ */
public static Instant minus(Instant instant, TemporalAmount amount) { public static Instant minus(Instant instant, TemporalAmount amount) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant(); return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant();
} }
/** /**
* * Minus.
* @param instant *
* @param amountToAdd * @param instant the instant
* @param unit * @param amountToAdd the amount to add
* @return * @param unit the unit
* @return the instant
*/ */
public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) { public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit) return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit)
@ -61,10 +64,11 @@ public class InstantHelper {
} }
/** /**
* * Truncate.
* @param instant *
* @param unit * @param instant the instant
* @return * @param unit the unit
* @return the instant
*/ */
public static Instant truncate(Instant instant, TemporalUnit unit) { public static Instant truncate(Instant instant, TemporalUnit unit) {
if (ChronoUnit.YEARS.equals(unit)) { if (ChronoUnit.YEARS.equals(unit)) {

View File

@ -34,8 +34,7 @@ import de.bstly.board.repository.EntryRepository;
import de.bstly.board.repository.LocalUserRepository; import de.bstly.board.repository.LocalUserRepository;
/** /**
* @author monitoring@bstly.de * The Class UserManager.
*
*/ */
@Service @Service
public class UserManager implements UserDetailsService, SmartInitializingSingleton { public class UserManager implements UserDetailsService, SmartInitializingSingleton {
@ -44,18 +43,27 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
@Autowired @Autowired
private LocalUserRepository localUserRepository; private LocalUserRepository localUserRepository;
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;
@Autowired @Autowired
private EntryRepository entryRepository; private EntryRepository entryRepository;
private QLocalUser qLocalUser = QLocalUser.localUser; private QLocalUser qLocalUser = QLocalUser.localUser;
private QEntry qEntry = QEntry.entry; private QEntry qEntry = QEntry.entry;
@Value("${admin.password:}") @Value("${admin.password:}")
private String adminPassword; private String adminPassword;
/*
* @see org.springframework.security.core.userdetails.UserDetailsService#
* loadUserByUsername(java.lang.String)
*/
/* /*
* @see * @see
* de.bstly.board.businesslogic.LocalUserManager#loadUserByUsername(java.lang. * de.bstly.board.businesslogic.LocalUserManager#loadUserByUsername(java.lang.
@ -79,6 +87,10 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
return new User(username, localUser.getPasswordHash(), authorities); return new User(username, localUser.getPasswordHash(), authorities);
} }
/*
* @see org.springframework.beans.factory.SmartInitializingSingleton#
* afterSingletonsInstantiated()
*/
/* /*
* *
* @see org.springframework.beans.factory.SmartInitializingSingleton# * @see org.springframework.beans.factory.SmartInitializingSingleton#
@ -102,27 +114,30 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
} }
/** /**
* * Gets the by username.
* @param username *
* @return * @param username the username
* @return the by username
*/ */
public LocalUser getByUsername(String username) { public LocalUser getByUsername(String username) {
return localUserRepository.findById(username).orElse(null); return localUserRepository.findById(username).orElse(null);
} }
/** /**
* * Gets the by external id.
* @param externalId *
* @return * @param externalId the external id
* @return the by external id
*/ */
public LocalUser getByExternalId(String externalId) { public LocalUser getByExternalId(String externalId) {
return localUserRepository.findOne(qLocalUser.externalId.eq(externalId)).orElse(null); return localUserRepository.findOne(qLocalUser.externalId.eq(externalId)).orElse(null);
} }
/** /**
* * Gets the by auth.
* @param authentication *
* @return * @param authentication the authentication
* @return the by auth
*/ */
public LocalUser getByAuth(Authentication authentication) { public LocalUser getByAuth(Authentication authentication) {
if (authentication != null) { if (authentication != null) {
@ -181,8 +196,10 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
} }
/** /**
* * Apply metadata.
* @param user *
* @param username the username
* @param user the user
*/ */
public void applyMetadata(String username, LocalUser user) { public void applyMetadata(String username, LocalUser user) {
if (user.getUsername().equals(username) && !user.getMetadata().containsKey("self")) { if (user.getUsername().equals(username) && !user.getMetadata().containsKey("self")) {
@ -199,17 +216,20 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
} }
/** /**
* * Save.
* @param localUser *
* @return * @param localUser the local user
* @return the local user
*/ */
public LocalUser save(LocalUser localUser) { public LocalUser save(LocalUser localUser) {
return localUserRepository.save(localUser); return localUserRepository.save(localUser);
} }
/** /**
* @param username * Exists.
* @return *
* @param username the username
* @return true, if successful
*/ */
public boolean exists(String username) { public boolean exists(String username) {
return localUserRepository.existsById(username); return localUserRepository.existsById(username);

View File

@ -13,22 +13,23 @@ import de.bstly.board.model.VoteType;
import de.bstly.board.repository.VoteRepository; import de.bstly.board.repository.VoteRepository;
/** /**
* @author Lurkars * The Class VoteManager.
*
*/ */
@Component @Component
public class VoteManager { public class VoteManager {
@Autowired @Autowired
private VoteRepository voteRepository; private VoteRepository voteRepository;
private QVote qVote = QVote.vote; private QVote qVote = QVote.vote;
/** /**
* * Gets the.
* @param author *
* @param targetType * @param author the author
* @param target * @param targetType the target type
* @return * @param target the target
* @return the vote
*/ */
public Vote get(String author, Types targetType, Long target) { public Vote get(String author, Types targetType, Long target) {
return voteRepository.findOne(qVote.author.eq(author).and(qVote.targetType.eq(targetType)) return voteRepository.findOne(qVote.author.eq(author).and(qVote.targetType.eq(targetType))
@ -36,25 +37,29 @@ public class VoteManager {
} }
/** /**
* * Save.
* @param vote *
* @return * @param vote the vote
* @return the vote
*/ */
public Vote save(Vote vote) { public Vote save(Vote vote) {
return voteRepository.save(vote); return voteRepository.save(vote);
} }
/** /**
* * Delete.
* @param vote *
* @param vote the vote
*/ */
public void delete(Vote vote) { public void delete(Vote vote) {
voteRepository.delete(vote); voteRepository.delete(vote);
} }
/** /**
* * Delete by target.
* @param vote *
* @param target the target
* @param targetType the target type
*/ */
public void deleteByTarget(Long target, Types targetType) { public void deleteByTarget(Long target, Types targetType) {
for (Vote vote : voteRepository for (Vote vote : voteRepository
@ -64,10 +69,11 @@ public class VoteManager {
} }
/** /**
* * Gets the points.
* @param target *
* @param targetType * @param target the target
* @return * @param targetType the target type
* @return the points
*/ */
public Long getPoints(Long target, Types targetType) { public Long getPoints(Long target, Types targetType) {
return voteRepository return voteRepository

View File

@ -11,49 +11,53 @@ import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit; import java.time.temporal.TemporalUnit;
/** /**
* @author _bastler@bstly.de * The Class InstantHelper.
*
*/ */
public class InstantHelper { public class InstantHelper {
/** /**
* * Plus.
* @param instant *
* @param amount * @param instant the instant
* @return * @param amount the amount
* @return the instant
*/ */
public static Instant plus(Instant instant, TemporalAmount amount) { public static Instant plus(Instant instant, TemporalAmount amount) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant(); return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant();
} }
/** /**
* * Plus.
* @param instant *
* @param amountToAdd * @param instant the instant
* @param unit * @param amountToAdd the amount to add
* @return * @param unit the unit
* @return the instant
*/ */
public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) { public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant(); return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant();
} }
/** /**
* * Minus.
* @param instant *
* @param amount * @param instant the instant
* @return * @param amount the amount
* @return the instant
*/ */
public static Instant minus(Instant instant, TemporalAmount amount) { public static Instant minus(Instant instant, TemporalAmount amount) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant(); return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant();
} }
/** /**
* * Minus.
* @param instant *
* @param amountToAdd * @param instant the instant
* @param unit * @param amountToAdd the amount to add
* @return * @param unit the unit
* @return the instant
*/ */
public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) { public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) {
return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit) return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit)
@ -61,10 +65,11 @@ public class InstantHelper {
} }
/** /**
* * Truncate.
* @param instant *
* @param unit * @param instant the instant
* @return * @param unit the unit
* @return the instant
*/ */
public static Instant truncate(Instant instant, TemporalUnit unit) { public static Instant truncate(Instant instant, TemporalUnit unit) {
if (ChronoUnit.YEARS.equals(unit)) { if (ChronoUnit.YEARS.equals(unit)) {

View File

@ -17,23 +17,25 @@ import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
/** /**
* * The Class AuthenticationController.
* @author _bastler@bstly.de
*
*/ */
@RestController @RestController
@RequestMapping("/auth") @RequestMapping("/auth")
public class AuthenticationController extends BaseController { public class AuthenticationController extends BaseController {
private static String authorizationRequestBaseUri = "oauth2/authorization"; private static String authorizationRequestBaseUri = "oauth2/authorization";
@Autowired @Autowired
private ClientRegistrationRepository clientRegistrationRepository; private ClientRegistrationRepository clientRegistrationRepository;
/** /**
* * Me.
* @return *
* @return the authentication
*/ */
@GetMapping @GetMapping
public Authentication me() { public Authentication me() {
@ -42,8 +44,9 @@ public class AuthenticationController extends BaseController {
} }
/** /**
* * Gets the external login urls.
* @return *
* @return the external login urls
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@GetMapping("external") @GetMapping("external")
@ -66,14 +69,22 @@ public class AuthenticationController extends BaseController {
return clients; return clients;
} }
/**
* The Class Client.
*/
protected static class Client { protected static class Client {
private String id; private String id;
private String loginUrl; private String loginUrl;
/** /**
* @param id * Instantiates a new client.
* @param loginUrl *
* @param id the id
* @param loginUrl the login url
*/ */
public Client(String id, String loginUrl) { public Client(String id, String loginUrl) {
super(); super();
@ -82,6 +93,8 @@ public class AuthenticationController extends BaseController {
} }
/** /**
* Gets the id.
*
* @return the id * @return the id
*/ */
public String getId() { public String getId() {
@ -89,21 +102,27 @@ public class AuthenticationController extends BaseController {
} }
/** /**
* @param id the id to set * Sets the id.
*
* @param id the new id
*/ */
public void setId(String id) { public void setId(String id) {
this.id = id; this.id = id;
} }
/** /**
* @return the loginUrl * Gets the login url.
*
* @return the login url
*/ */
public String getLoginUrl() { public String getLoginUrl() {
return loginUrl; return loginUrl;
} }
/** /**
* @param loginUrl the loginUrl to set * Sets the login url.
*
* @param loginUrl the new login url
*/ */
public void setLoginUrl(String loginUrl) { public void setLoginUrl(String loginUrl) {
this.loginUrl = loginUrl; this.loginUrl = loginUrl;

View File

@ -10,18 +10,20 @@ import org.springframework.security.core.context.SecurityContextHolder;
import de.bstly.board.businesslogic.UserManager; import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.model.LocalUser; import de.bstly.board.model.LocalUser;
/** /**
* @author monitoring@bstly.de * The Class BaseController.
*
*/ */
public class BaseController { public class BaseController {
@Autowired @Autowired
private UserManager localUserManager; private UserManager localUserManager;
/** /**
* * Authenticated.
* @return *
* @return true, if successful
*/ */
protected boolean authenticated() { protected boolean authenticated() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); Authentication auth = SecurityContextHolder.getContext().getAuthentication();
@ -29,8 +31,9 @@ public class BaseController {
} }
/** /**
* * Gets the current username.
* @return *
* @return the current username
*/ */
protected String getCurrentUsername() { protected String getCurrentUsername() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); Authentication auth = SecurityContextHolder.getContext().getAuthentication();
@ -38,8 +41,9 @@ public class BaseController {
} }
/** /**
* * Gets the local user.
* @return *
* @return the local user
*/ */
protected LocalUser getLocalUser() { protected LocalUser getLocalUser() {
return localUserManager.getByAuth(SecurityContextHolder.getContext().getAuthentication()); return localUserManager.getByAuth(SecurityContextHolder.getContext().getAuthentication());

View File

@ -0,0 +1,100 @@
/**
*
*/
package de.bstly.board.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.bstly.board.businesslogic.BookmarksManager;
import de.bstly.board.businesslogic.EntryManager;
import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.model.Entry;
/**
* The Class BookmarksController.
*/
@RestController
@RequestMapping("/b")
public class BookmarksController extends BaseController {
@Autowired
private BookmarksManager bookmarksManager;
@Autowired
private EntryManager entryManager;
@Value("${bstly.board.size:30}")
private int SIZE;
/**
* Gets the entries.
*
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @return the entries
*/
@PreAuthorize("isAuthenticated()")
@GetMapping()
public Page<Entry> getEntries(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter) {
if (sizeParameter.isPresent() && sizeParameter.get() > 100) {
sizeParameter = Optional.of(100);
}
Page<Entry> entries = entryManager.fetchByBookmarks(getCurrentUsername(),
pageParameter.orElse(0), sizeParameter.orElse(SIZE));
entryManager.applyMetadata(getCurrentUsername(), entries.getContent());
return entries;
}
/**
* Adds the entry.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()")
@PutMapping("/{id}")
public void addEntry(@PathVariable("id") Long id) {
if (!entryManager.exists(id)) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
}
if (bookmarksManager.hasEntry(getCurrentUsername(), id)) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
bookmarksManager.addEntry(getCurrentUsername(), id);
}
/**
* Removes the entry.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{id}")
public void removeEntry(@PathVariable("id") Long id) {
if (!entryManager.exists(id)) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
}
if (!bookmarksManager.hasEntry(getCurrentUsername(), id)) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
bookmarksManager.removeEntry(getCurrentUsername(), id);
}
}

View File

@ -29,26 +29,45 @@ import de.bstly.board.model.Types;
import de.bstly.board.model.Vote; import de.bstly.board.model.Vote;
import de.bstly.board.model.VoteType; import de.bstly.board.model.VoteType;
/** /**
* @author Lurkars * The Class CommentController.
*
*/ */
@RestController @RestController
@RequestMapping("/c") @RequestMapping("/c")
public class CommentController extends BaseController { public class CommentController extends BaseController {
@Autowired @Autowired
private CommentManager commentManager; private CommentManager commentManager;
@Autowired @Autowired
private CommentValidator commentValidator; private CommentValidator commentValidator;
@Autowired @Autowired
private VoteManager voteManager; private VoteManager voteManager;
@Value("${bstly.board.size:30}") @Value("${bstly.board.size:30}")
private int SIZE; private int SIZE;
@Value("${bstly.board.ranking.gravity:1.8}") @Value("${bstly.board.ranking.gravity:1.8}")
private double GRAVITY; private double GRAVITY;
/**
* Ranked comments.
*
* @param target the target
* @param parent the parent
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @param dateParameter the date parameter
* @param gravityParameter the gravity parameter
* @return the page
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping({ "/e/{target}", "/e/{target}/{parent}" }) @GetMapping({ "/e/{target}", "/e/{target}/{parent}" })
public Page<Comment> rankedComments(@PathVariable("target") Long target, public Page<Comment> rankedComments(@PathVariable("target") Long target,
@ -69,6 +88,13 @@ public class CommentController extends BaseController {
// return comments; // return comments;
} }
/**
* Count comments.
*
* @param target the target
* @param parent the parent
* @return the long
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping({ "/c/{target}", "/c/{target}/{parent}" }) @GetMapping({ "/c/{target}", "/c/{target}/{parent}" })
public Long countComments(@PathVariable("target") Long target, public Long countComments(@PathVariable("target") Long target,
@ -76,6 +102,16 @@ public class CommentController extends BaseController {
return commentManager.count(target, parent.orElse(null)); return commentManager.count(target, parent.orElse(null));
} }
/**
* New comments.
*
* @param target the target
* @param parent the parent
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @param dateParameter the date parameter
* @return the page
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping({ "/e/new/{target}", "/e/new/{target}/{parent}" }) @GetMapping({ "/e/new/{target}", "/e/new/{target}/{parent}" })
public Page<Comment> newComments(@PathVariable("target") Long target, public Page<Comment> newComments(@PathVariable("target") Long target,
@ -90,6 +126,12 @@ public class CommentController extends BaseController {
return comments; return comments;
} }
/**
* Gets the comment.
*
* @param id the id
* @return the comment
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/{id}") @GetMapping("/{id}")
public Comment getComment(@PathVariable("id") Long id) { public Comment getComment(@PathVariable("id") Long id) {
@ -104,6 +146,12 @@ public class CommentController extends BaseController {
return comment; return comment;
} }
/**
* Creates the comment.
*
* @param comment the comment
* @return the comment
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PostMapping() @PostMapping()
public Comment createComment(@RequestBody Comment comment) { public Comment createComment(@RequestBody Comment comment) {

View File

@ -32,61 +32,91 @@ import de.bstly.board.repository.CommentRepository;
import de.bstly.board.repository.LocalUserRepository; import de.bstly.board.repository.LocalUserRepository;
import de.bstly.board.repository.VoteRepository; import de.bstly.board.repository.VoteRepository;
/** /**
* * The Class DebugController.
* @author _bastler@bstly.de
*
*/ */
@RestController @RestController
@RequestMapping("/debug") @RequestMapping("/debug")
public class DebugController extends BaseController { public class DebugController extends BaseController {
/**
* logger
*/
private Logger logger = LogManager.getLogger(DebugController.class); private Logger logger = LogManager.getLogger(DebugController.class);
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Autowired @Autowired
private LocalUserRepository localUserRepository; private LocalUserRepository localUserRepository;
@Autowired @Autowired
private CommentRepository commentRepository; private CommentRepository commentRepository;
@Autowired @Autowired
private VoteRepository voteRepository; private VoteRepository voteRepository;
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;
@Value("${debug.random.users:0}") @Value("${debug.random.users:0}")
private int users; private int users;
@Value("${debug.random.minEntries:0}") @Value("${debug.random.minEntries:0}")
private int minEntries; private int minEntries;
@Value("${debug.random.maxEntries:10}") @Value("${debug.random.maxEntries:10}")
private int maxEntries; private int maxEntries;
@Value("${debug.random.entryAge:63115200}") @Value("${debug.random.entryAge:63115200}")
private long entryAge; private long entryAge;
@Value("${debug.random.minComments:0}") @Value("${debug.random.minComments:0}")
private int minComments; private int minComments;
@Value("${debug.random.maxComments:10}") @Value("${debug.random.maxComments:10}")
private int maxComments; private int maxComments;
@Value("${debug.random.subCommentsFactor:0.5}") @Value("${debug.random.subCommentsFactor:0.5}")
private double subCommentsFactor; private double subCommentsFactor;
@Value("${debug.random.subCommentsThresh:0.3}") @Value("${debug.random.subCommentsThresh:0.3}")
private double subCommentsThresh; private double subCommentsThresh;
@Value("${debug.random.subCommentsDepth:2}") @Value("${debug.random.subCommentsDepth:2}")
private int subCommentsDepth; private int subCommentsDepth;
@Value("${debug.random.minUpvotes:5}") @Value("${debug.random.minUpvotes:5}")
private int minUpvotes; private int minUpvotes;
@Value("${debug.random.maxUpvotes:10}") @Value("${debug.random.maxUpvotes:10}")
private int maxUpvotes; private int maxUpvotes;
@Value("${debug.random.minDownvotes:0}") @Value("${debug.random.minDownvotes:0}")
private int minDownvotes; private int minDownvotes;
@Value("${debug.random.maxDownvotes:10}") @Value("${debug.random.maxDownvotes:10}")
private int maxDownvotes; private int maxDownvotes;
/** /**
* * Random.
* @return
*/ */
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/random") @GetMapping("/random")
@ -120,6 +150,12 @@ public class DebugController extends BaseController {
logger.warn("finished random generation"); logger.warn("finished random generation");
} }
/**
* Entries.
*
* @param username the username
* @param userCount the user count
*/
protected void entries(String username, long userCount) { protected void entries(String username, long userCount) {
long numEntries = RandomUtils.nextLong(minEntries, maxEntries); long numEntries = RandomUtils.nextLong(minEntries, maxEntries);
for (int i = 0; i < numEntries; i++) { for (int i = 0; i < numEntries; i++) {
@ -145,6 +181,13 @@ public class DebugController extends BaseController {
+ "'"); + "'");
} }
/**
* Comments.
*
* @param target the target
* @param date the date
* @param userCount the user count
*/
protected void comments(Long target, Instant date, long userCount) { protected void comments(Long target, Instant date, long userCount) {
long numComments = RandomUtils.nextLong(minComments, maxComments); long numComments = RandomUtils.nextLong(minComments, maxComments);
logger.debug("Create " logger.debug("Create "
@ -171,6 +214,17 @@ public class DebugController extends BaseController {
} }
} }
/**
* Sub comments.
*
* @param target the target
* @param parent the parent
* @param date the date
* @param factor the factor
* @param thresh the thresh
* @param depth the depth
* @param userCount the user count
*/
protected void subComments(Long target, Long parent, Instant date, double factor, double thresh, protected void subComments(Long target, Long parent, Instant date, double factor, double thresh,
int depth, long userCount) { int depth, long userCount) {
if (depth < subCommentsDepth && RandomUtils.nextDouble(0, 1) < thresh) { if (depth < subCommentsDepth && RandomUtils.nextDouble(0, 1) < thresh) {
@ -201,6 +255,13 @@ public class DebugController extends BaseController {
} }
} }
/**
* Votes.
*
* @param target the target
* @param targetType the target type
* @param userCount the user count
*/
protected void votes(Long target, Types targetType, long userCount) { protected void votes(Long target, Types targetType, long userCount) {
long numUpvotes = RandomUtils.nextLong(minUpvotes, maxUpvotes); long numUpvotes = RandomUtils.nextLong(minUpvotes, maxUpvotes);
logger.debug("Create " logger.debug("Create "

View File

@ -34,8 +34,7 @@ import de.bstly.board.model.Vote;
import de.bstly.board.model.VoteType; import de.bstly.board.model.VoteType;
/** /**
* @author Lurkars * The Class EntryController.
*
*/ */
@RestController @RestController
@RequestMapping("/e") @RequestMapping("/e")
@ -43,16 +42,28 @@ public class EntryController extends BaseController {
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;
@Autowired @Autowired
private EntryValidator entryValidator; private EntryValidator entryValidator;
@Autowired @Autowired
private VoteManager voteManager; private VoteManager voteManager;
@Value("${bstly.board.size:30}") @Value("${bstly.board.size:30}")
private int SIZE; private int SIZE;
@Value("${bstly.board.ranking.gravity:1.8}") @Value("${bstly.board.ranking.gravity:1.8}")
private double GRAVITY; private double GRAVITY;
/**
* Ranked entries.
*
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @param dateParameter the date parameter
* @param gravityParameter the gravity parameter
* @return the page
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping() @GetMapping()
public Page<Entry> rankedEntries(@RequestParam("page") Optional<Integer> pageParameter, public Page<Entry> rankedEntries(@RequestParam("page") Optional<Integer> pageParameter,
@ -64,9 +75,9 @@ public class EntryController extends BaseController {
sizeParameter = Optional.of(100); sizeParameter = Optional.of(100);
} }
Page<RankedEntry> entries = entryManager.directFetchByRanking( Page<RankedEntry> entries = entryManager.fetchByRanking(dateParameter.orElse(Instant.now()),
dateParameter.orElse(Instant.now()), gravityParameter.orElse(GRAVITY), gravityParameter.orElse(GRAVITY), pageParameter.orElse(0),
pageParameter.orElse(0), sizeParameter.orElse(SIZE)); sizeParameter.orElse(SIZE));
Page<Entry> transformed = new PageImpl<Entry>( Page<Entry> transformed = new PageImpl<Entry>(
entries.getContent().stream().map(rankedEntry -> Entry.fromRankedEntry(rankedEntry)) entries.getContent().stream().map(rankedEntry -> Entry.fromRankedEntry(rankedEntry))
@ -77,22 +88,14 @@ public class EntryController extends BaseController {
return transformed; return transformed;
} }
@PreAuthorize("isAuthenticated()") /**
@GetMapping("ranked") * New entries.
public Page<Entry> rankedEntries(@RequestParam("page") Optional<Integer> pageParameter, *
@RequestParam("size") Optional<Integer> sizeParameter) { * @param pageParameter the page parameter
* @param sizeParameter the size parameter
if (sizeParameter.isPresent() && sizeParameter.get() > 100) { * @param dateParameter the date parameter
sizeParameter = Optional.of(100); * @return the page
} */
Page<Entry> entries = entryManager.fetchByRanking(pageParameter.orElse(0),
sizeParameter.orElse(SIZE));
entryManager.applyMetadata(getCurrentUsername(), entries.getContent());
return entries;
}
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/new") @GetMapping("/new")
public Page<Entry> newEntries(@RequestParam("page") Optional<Integer> pageParameter, public Page<Entry> newEntries(@RequestParam("page") Optional<Integer> pageParameter,
@ -109,6 +112,12 @@ public class EntryController extends BaseController {
return entries; return entries;
} }
/**
* Gets the entry.
*
* @param id the id
* @return the entry
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/{id}") @GetMapping("/{id}")
public Entry getEntry(@PathVariable("id") Long id) { public Entry getEntry(@PathVariable("id") Long id) {
@ -119,10 +128,16 @@ public class EntryController extends BaseController {
} }
entryManager.applyMetadata(getCurrentUsername(), entry); entryManager.applyMetadata(getCurrentUsername(), entry);
return entry; return entry;
} }
/**
* Creates the entry.
*
* @param entry the entry
* @return the entry
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PostMapping() @PostMapping()
public Entry createEntry(@RequestBody Entry entry) { public Entry createEntry(@RequestBody Entry entry) {

View File

@ -8,26 +8,43 @@ import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Lists;
import de.bstly.board.businesslogic.CommentManager; import de.bstly.board.businesslogic.CommentManager;
import de.bstly.board.businesslogic.EntryManager; import de.bstly.board.businesslogic.EntryManager;
import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.controller.support.EntityResponseStatusException; import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.model.LocalUser;
/** /**
* @author Lurkars * The Class ModerationController.
*
*/ */
@RestController @RestController
@RequestMapping("/m") @RequestMapping("/m")
public class ModerationController { public class ModerationController {
@Autowired @Autowired
private CommentManager commentManager; private CommentManager commentManager;
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;
@Autowired
private UserManager userManager;
/**
* Delete comment.
*
* @param id the id
*/
@PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_MOD')") @PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_MOD')")
@DeleteMapping("/c/{id}") @DeleteMapping("/c/{id}")
public void deleteComment(@PathVariable("id") Long id) { public void deleteComment(@PathVariable("id") Long id) {
@ -38,6 +55,11 @@ public class ModerationController {
commentManager.delete(commentManager.get(id)); commentManager.delete(commentManager.get(id));
} }
/**
* Delete entry.
*
* @param id the id
*/
@PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_MOD')") @PreAuthorize("hasRole('ROLE_ADMIN') || hasRole('ROLE_MOD')")
@DeleteMapping("/e/{id}") @DeleteMapping("/e/{id}")
public void deleteEntry(@PathVariable("id") Long id) { public void deleteEntry(@PathVariable("id") Long id) {
@ -47,4 +69,58 @@ public class ModerationController {
entryManager.delete(entryManager.get(id)); entryManager.delete(entryManager.get(id));
} }
/**
* Make mod.
*
* @param username the username
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PutMapping("/u/{username}")
public void makeMod(@PathVariable("username") String username) {
LocalUser user = userManager.getByUsername(username);
if (user == null) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
}
if (user.getRoles() == null) {
user.setRoles(Lists.newArrayList());
}
if (user.getRoles().contains("ROLE_MOD")) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
user.getRoles().add("ROLE_MOD");
userManager.save(user);
}
/**
* Unmake mode.
*
* @param username the username
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/u/{username}")
public void unmakeMode(@PathVariable("username") String username) {
LocalUser user = userManager.getByUsername(username);
if (user == null) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
}
if (user.getRoles() == null) {
user.setRoles(Lists.newArrayList());
}
if (!user.getRoles().contains("ROLE_MOD")) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
user.getRoles().remove("ROLE_MOD");
userManager.save(user);
}
} }

View File

@ -19,17 +19,24 @@ import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.controller.support.EntityResponseStatusException; import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.model.LocalUser; import de.bstly.board.model.LocalUser;
/** /**
* @author monitoring@bstly.de * The Class UserController.
*
*/ */
@RestController @RestController
@RequestMapping("/u") @RequestMapping("/u")
public class UserController extends BaseController { public class UserController extends BaseController {
@Autowired @Autowired
private UserManager userManager; private UserManager userManager;
/**
* Gets the user.
*
* @param usernameParameter the username parameter
* @return the user
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping({ "", "/{username}" }) @GetMapping({ "", "/{username}" })
public LocalUser getUser(@PathVariable("username") Optional<String> usernameParameter) { public LocalUser getUser(@PathVariable("username") Optional<String> usernameParameter) {
@ -54,6 +61,12 @@ public class UserController extends BaseController {
return user; return user;
} }
/**
* Update user.
*
* @param user the user
* @return the local user
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PostMapping() @PostMapping()
public LocalUser updateUser(@RequestBody LocalUser user) { public LocalUser updateUser(@RequestBody LocalUser user) {

View File

@ -21,21 +21,32 @@ import de.bstly.board.model.Types;
import de.bstly.board.model.Vote; import de.bstly.board.model.Vote;
import de.bstly.board.model.VoteType; import de.bstly.board.model.VoteType;
/** /**
* @author monitoring@bstly.de * The Class VoteController.
*
*/ */
@RestController @RestController
@RequestMapping("/v") @RequestMapping("/v")
public class VoteController extends BaseController { public class VoteController extends BaseController {
@Autowired @Autowired
private VoteManager voteManager; private VoteManager voteManager;
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;
@Autowired @Autowired
private CommentManager commentManager; private CommentManager commentManager;
/**
* Gets the entry points.
*
* @param id the id
* @return the entry points
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/e/{id}") @GetMapping("/e/{id}")
public long getEntryPoints(@PathVariable("id") Long id) { public long getEntryPoints(@PathVariable("id") Long id) {
@ -46,6 +57,11 @@ public class VoteController extends BaseController {
return voteManager.getPoints(id, Types.entry); return voteManager.getPoints(id, Types.entry);
} }
/**
* Vote entry up.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PutMapping("/e/{id}/up") @PutMapping("/e/{id}/up")
public void voteEntryUp(@PathVariable("id") Long id) { public void voteEntryUp(@PathVariable("id") Long id) {
@ -67,6 +83,11 @@ public class VoteController extends BaseController {
} }
} }
/**
* Vote entry down.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PutMapping("/e/{id}/down") @PutMapping("/e/{id}/down")
public void voteEntryDown(@PathVariable("id") Long id) { public void voteEntryDown(@PathVariable("id") Long id) {
@ -88,6 +109,11 @@ public class VoteController extends BaseController {
} }
} }
/**
* Unvote entry.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@DeleteMapping("/e/{id}") @DeleteMapping("/e/{id}")
public void unvoteEntry(@PathVariable("id") Long id) { public void unvoteEntry(@PathVariable("id") Long id) {
@ -103,6 +129,12 @@ public class VoteController extends BaseController {
voteManager.delete(vote); voteManager.delete(vote);
} }
/**
* Gets the comment points.
*
* @param id the id
* @return the comment points
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/c/{id}") @GetMapping("/c/{id}")
public long getCommentPoints(@PathVariable("id") Long id) { public long getCommentPoints(@PathVariable("id") Long id) {
@ -113,6 +145,11 @@ public class VoteController extends BaseController {
return voteManager.getPoints(id, Types.comment); return voteManager.getPoints(id, Types.comment);
} }
/**
* Vote comment up.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PutMapping("/c/{id}/up") @PutMapping("/c/{id}/up")
public void voteCommentUp(@PathVariable("id") Long id) { public void voteCommentUp(@PathVariable("id") Long id) {
@ -134,6 +171,11 @@ public class VoteController extends BaseController {
} }
} }
/**
* Vote comment down.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@PutMapping("/c/{id}/down") @PutMapping("/c/{id}/down")
public void voteCommentDown(@PathVariable("id") Long id) { public void voteCommentDown(@PathVariable("id") Long id) {
@ -155,6 +197,11 @@ public class VoteController extends BaseController {
} }
} }
/**
* Unvote comment.
*
* @param id the id
*/
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@DeleteMapping("/c/{id}") @DeleteMapping("/c/{id}")
public void unvoteComment(@PathVariable("id") Long id) { public void unvoteComment(@PathVariable("id") Long id) {

View File

@ -10,19 +10,19 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
/** /**
* * The Class ControllerExceptionHandler.
* @author monitoring@bstly.de
*
*/ */
@ControllerAdvice @ControllerAdvice
public class ControllerExceptionHandler extends ResponseEntityExceptionHandler { public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
/** /**
* * Handle response entity status exception.
* @param exception *
* @param request * @param exception the exception
* @return * @param request the request
* @return the response entity
*/ */
@ExceptionHandler(value = { EntityResponseStatusException.class }) @ExceptionHandler(value = { EntityResponseStatusException.class })
protected ResponseEntity<Object> handleResponseEntityStatusException(RuntimeException exception, protected ResponseEntity<Object> handleResponseEntityStatusException(RuntimeException exception,

View File

@ -10,45 +10,47 @@ import org.springframework.core.NestedRuntimeException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* * The Class EntityResponseStatusException.
* @author monitoring@bstly.de
*
*/ */
public class EntityResponseStatusException extends NestedRuntimeException { public class EntityResponseStatusException extends NestedRuntimeException {
/**
* default serialVersionUID
*/
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final HttpStatus status; private final HttpStatus status;
@Nullable @Nullable
private final Object body; private final Object body;
/** /**
* * Instantiates a new entity response status exception.
* @param status *
* @param status the status
*/ */
public EntityResponseStatusException(HttpStatus status) { public EntityResponseStatusException(HttpStatus status) {
this(null, status); this(null, status);
} }
/** /**
* * Instantiates a new entity response status exception.
* @param body *
* @param status * @param body the body
* @param status the status
*/ */
public EntityResponseStatusException(@Nullable Object body, HttpStatus status) { public EntityResponseStatusException(@Nullable Object body, HttpStatus status) {
this(body, status, null); this(body, status, null);
} }
/** /**
* * Instantiates a new entity response status exception.
* @param body *
* @param status * @param body the body
* @param cause * @param status the status
* @param cause the cause
*/ */
public EntityResponseStatusException(@Nullable Object body, HttpStatus status, @Nullable Throwable cause) { public EntityResponseStatusException(@Nullable Object body, HttpStatus status, @Nullable Throwable cause) {
super(null, cause); super(null, cause);
@ -58,25 +60,26 @@ public class EntityResponseStatusException extends NestedRuntimeException {
} }
/** /**
* * Gets the status.
* @return *
* @return the status
*/ */
public HttpStatus getStatus() { public HttpStatus getStatus() {
return this.status; return this.status;
} }
/** /**
* * Gets the body.
* @return *
* @return the body
*/ */
@Nullable @Nullable
public Object getBody() { public Object getBody() {
return this.body; return this.body;
} }
/** /*
* * @see org.springframework.core.NestedRuntimeException#getMessage()
* @return
*/ */
@Override @Override
public String getMessage() { public String getMessage() {

View File

@ -6,21 +6,21 @@ package de.bstly.board.controller.support;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.validation.AbstractBindingResult; import org.springframework.validation.AbstractBindingResult;
/** /**
* * The Class RequestBodyErrors.
* @author _bastler@bstly.de
*
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class RequestBodyErrors extends AbstractBindingResult { public class RequestBodyErrors extends AbstractBindingResult {
@Nullable @Nullable
private final Object target; private final Object target;
/** /**
* * Instantiates a new request body errors.
* @param target *
* @param objectName * @param target the target
*/ */
public RequestBodyErrors(@Nullable Object target) { public RequestBodyErrors(@Nullable Object target) {
super("request-body"); super("request-body");
@ -35,6 +35,9 @@ public class RequestBodyErrors extends AbstractBindingResult {
return target; return target;
} }
/*
* @see org.springframework.validation.AbstractBindingResult#getActualFieldValue(java.lang.String)
*/
/* /*
* @see * @see
* org.springframework.validation.AbstractBindingResult#getActualFieldValue(java * org.springframework.validation.AbstractBindingResult#getActualFieldValue(java

View File

@ -13,15 +13,18 @@ import de.bstly.board.businesslogic.CommentManager;
import de.bstly.board.businesslogic.EntryManager; import de.bstly.board.businesslogic.EntryManager;
import de.bstly.board.model.Comment; import de.bstly.board.model.Comment;
/** /**
* @author monitoring@bstly.de * The Class CommentValidator.
*
*/ */
@Component @Component
public class CommentValidator implements Validator { public class CommentValidator implements Validator {
@Autowired @Autowired
private CommentManager commentManager; private CommentManager commentManager;
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;

View File

@ -12,13 +12,14 @@ import org.springframework.validation.Validator;
import de.bstly.board.model.Entry; import de.bstly.board.model.Entry;
import de.bstly.board.model.EntryType; import de.bstly.board.model.EntryType;
/** /**
* @author monitoring@bstly.de * The Class EntryValidator.
*
*/ */
@Component @Component
public class EntryValidator implements Validator { public class EntryValidator implements Validator {
private UrlValidator urlValidator = new UrlValidator(); private UrlValidator urlValidator = new UrlValidator();
/* /*

View File

@ -7,19 +7,19 @@ import org.springframework.context.ApplicationEvent;
import de.bstly.board.model.Vote; import de.bstly.board.model.Vote;
/** /**
* @author Lurkars * The Class VotedEvent.
*
*/ */
public class VotedEvent extends ApplicationEvent { public class VotedEvent extends ApplicationEvent {
/**
*
*/
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* @param source * Instantiates a new voted event.
*
* @param vote the vote
*/ */
public VotedEvent(Vote vote) { public VotedEvent(Vote vote) {
super(vote); super(vote);

View File

@ -28,34 +28,42 @@ import com.google.gson.JsonParser;
import de.bstly.board.i18n.model.I18n; import de.bstly.board.i18n.model.I18n;
import de.bstly.board.i18n.repository.I18nRepository; import de.bstly.board.i18n.repository.I18nRepository;
/** /**
* @author _bastler@bstly.de * The Class I18nManager.
*
*/ */
@Component @Component
public class I18nManager implements SmartInitializingSingleton { public class I18nManager implements SmartInitializingSingleton {
private Logger logger = LoggerFactory.getLogger(I18nManager.class); private Logger logger = LoggerFactory.getLogger(I18nManager.class);
@Autowired @Autowired
private I18nRepository i18nRepository; private I18nRepository i18nRepository;
@Autowired @Autowired
private ResourceLoader resourceLoader; private ResourceLoader resourceLoader;
private Gson gson = new Gson(); private Gson gson = new Gson();
/** /**
* * Gets the.
* @param locale *
* @return * @param locale the locale
* @return the i 18 n
*/ */
public I18n get(String locale) { public I18n get(String locale) {
return i18nRepository.findById(locale).orElse(null); return i18nRepository.findById(locale).orElse(null);
} }
/** /**
* * Gets the label.
* @param locale *
* @return * @param locale the locale
* @return the label
*/ */
public JsonObject getLabel(String locale) { public JsonObject getLabel(String locale) {
I18n i18n = get(locale); I18n i18n = get(locale);
@ -70,17 +78,19 @@ public class I18nManager implements SmartInitializingSingleton {
} }
/** /**
* * Gets the locales.
* @return *
* @return the locales
*/ */
public List<String> getLocales() { public List<String> getLocales() {
return i18nRepository.findAll().stream().map(I18n::getLocale).collect(Collectors.toList()); return i18nRepository.findAll().stream().map(I18n::getLocale).collect(Collectors.toList());
} }
/** /**
* * Extend json object.
* @param dest *
* @param src * @param dest the dest
* @param src the src
*/ */
protected void extendJsonObject(JsonObject dest, JsonObject src) { protected void extendJsonObject(JsonObject dest, JsonObject src) {
for (Entry<String, JsonElement> srcEntry : src.entrySet()) { for (Entry<String, JsonElement> srcEntry : src.entrySet()) {
@ -100,10 +110,11 @@ public class I18nManager implements SmartInitializingSingleton {
} }
/** /**
* * Adds the label.
* @param locale *
* @param newLabel * @param locale the locale
* @return * @param newLabel the new label
* @return the i 18 n
*/ */
public I18n addLabel(String locale, JsonObject newLabel) { public I18n addLabel(String locale, JsonObject newLabel) {
JsonObject label = getLabel(locale); JsonObject label = getLabel(locale);
@ -122,10 +133,11 @@ public class I18nManager implements SmartInitializingSingleton {
} }
/** /**
* * Sets the label.
* @param locale *
* @param label * @param locale the locale
* @return * @param label the label
* @return the i 18 n
*/ */
public I18n setLabel(String locale, JsonObject label) { public I18n setLabel(String locale, JsonObject label) {
I18n i18n = new I18n(); I18n i18n = new I18n();
@ -136,8 +148,9 @@ public class I18nManager implements SmartInitializingSingleton {
} }
/** /**
* * Delete label.
* @param locale *
* @param locale the locale
*/ */
public void deleteLabel(String locale) { public void deleteLabel(String locale) {
if (i18nRepository.existsById(locale)) { if (i18nRepository.existsById(locale)) {
@ -145,6 +158,9 @@ public class I18nManager implements SmartInitializingSingleton {
} }
} }
/*
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
*/
/* /*
* @see org.springframework.beans.factory.SmartInitializingSingleton# * @see org.springframework.beans.factory.SmartInitializingSingleton#
* afterSingletonsInstantiated() * afterSingletonsInstantiated()

View File

@ -27,21 +27,25 @@ import com.google.gson.JsonObject;
import de.bstly.board.controller.BaseController; import de.bstly.board.controller.BaseController;
import de.bstly.board.i18n.businesslogic.I18nManager; import de.bstly.board.i18n.businesslogic.I18nManager;
/** /**
* @author _bastler@bstly.de * The Class I18nController.
*
*/ */
@RestController @RestController
@RequestMapping("/i18n") @RequestMapping("/i18n")
public class I18nController extends BaseController { public class I18nController extends BaseController {
@Autowired @Autowired
private I18nManager i18nManager; private I18nManager i18nManager;
private Gson gson = new Gson(); private Gson gson = new Gson();
/** /**
* * Gets the locales.
* @return *
* @return the locales
*/ */
@GetMapping @GetMapping
public List<String> getLocales() { public List<String> getLocales() {
@ -49,11 +53,13 @@ public class I18nController extends BaseController {
} }
/** /**
* * Gets the label.
* @param locale *
* @param response * @param locale the locale
* @throws JsonIOException * @param response the response
* @throws IOException * @return the label
* @throws JsonIOException the json IO exception
* @throws IOException Signals that an I/O exception has occurred.
*/ */
@GetMapping("/{locale}") @GetMapping("/{locale}")
public void getLabel(@PathVariable("locale") String locale, HttpServletResponse response) public void getLabel(@PathVariable("locale") String locale, HttpServletResponse response)
@ -66,9 +72,10 @@ public class I18nController extends BaseController {
} }
/** /**
* * Sets the label.
* @param locale *
* @param label * @param locale the locale
* @param label the label
*/ */
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/{locale}") @PostMapping("/{locale}")
@ -81,9 +88,10 @@ public class I18nController extends BaseController {
} }
/** /**
* * Adds the label.
* @param locale *
* @param label * @param locale the locale
* @param label the label
*/ */
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@PutMapping("/{locale}") @PutMapping("/{locale}")
@ -96,8 +104,9 @@ public class I18nController extends BaseController {
} }
/** /**
* * Delete locale.
* @param locale *
* @param locale the locale
*/ */
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{locale}") @DeleteMapping("/{locale}")

View File

@ -10,30 +10,27 @@ import javax.persistence.Lob;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
/** /**
* * The Class I18n.
* @author _bastler@bstly.de
*
*/ */
@Entity @Entity
@Table(name = "i18n", uniqueConstraints = @UniqueConstraint(columnNames = { "locale" })) @Table(name = "i18n", uniqueConstraints = @UniqueConstraint(columnNames = { "locale" }))
public class I18n { public class I18n {
/**
*
*/
@Id @Id
@Column(name = "locale", unique = true, nullable = false) @Column(name = "locale", unique = true, nullable = false)
private String locale; private String locale;
/**
*
*/
@Lob @Lob
@Column(name = "label") @Column(name = "label")
private String label; private String label;
/** /**
* Gets the locale.
*
* @return the locale * @return the locale
*/ */
public String getLocale() { public String getLocale() {
@ -41,13 +38,17 @@ public class I18n {
} }
/** /**
* @param locale the locale to set * Sets the locale.
*
* @param locale the new locale
*/ */
public void setLocale(String locale) { public void setLocale(String locale) {
this.locale = locale; this.locale = locale;
} }
/** /**
* Gets the label.
*
* @return the label * @return the label
*/ */
public String getLabel() { public String getLabel() {
@ -55,7 +56,9 @@ public class I18n {
} }
/** /**
* @param label the label to set * Sets the label.
*
* @param label the new label
*/ */
public void setLabel(String label) { public void setLabel(String label) {
this.label = label; this.label = label;

View File

@ -10,9 +10,7 @@ import org.springframework.stereotype.Repository;
import de.bstly.board.i18n.model.I18n; import de.bstly.board.i18n.model.I18n;
/** /**
* * The Interface I18nRepository.
* @author _bastler@bstly.de
*
*/ */
@Repository @Repository
public interface I18nRepository public interface I18nRepository

View File

@ -0,0 +1,90 @@
/**
*
*/
package de.bstly.board.model;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.google.common.collect.Lists;
/**
* The Class Bookmarks.
*/
@Entity
@Table(name = "bookmarks")
@EntityListeners({ AuditingEntityListener.class })
public class Bookmarks {
@Id
@Column(name = "username", nullable = false)
private String username;
@ElementCollection
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "bookmark_entries")
private List<Long> entries;
/**
* @param username
*/
public Bookmarks() {
super();
}
/**
* @param username
*/
public Bookmarks(String username) {
super();
this.username = username;
this.entries = Lists.newArrayList();
}
/**
* Gets the username.
*
* @return the username
*/
public String getUsername() {
return username;
}
/**
* Sets the username.
*
* @param username the new username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Gets the entries.
*
* @return the entries
*/
public List<Long> getEntries() {
return entries;
}
/**
* Sets the entries.
*
* @param entries the new entries
*/
public void setEntries(List<Long> entries) {
this.entries = entries;
}
}

View File

@ -20,34 +20,49 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
/** /**
* @author Lurkars * The Class Comment.
*
*/ */
@Entity @Entity
@Table(name = "comments") @Table(name = "comments")
@EntityListeners({ AuditingEntityListener.class }) @EntityListeners({ AuditingEntityListener.class })
public class Comment { public class Comment {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false) @Column(name = "id", nullable = false)
private Long id; private Long id;
@Column(name = "author", nullable = false) @Column(name = "author", nullable = false)
private String author; private String author;
@Column(name = "created", nullable = false) @Column(name = "created", nullable = false)
private Instant created; private Instant created;
@Column(name = "target", nullable = false) @Column(name = "target", nullable = false)
private Long target; private Long target;
@Column(name = "parent", nullable = true) @Column(name = "parent", nullable = true)
private Long parent; private Long parent;
@Lob @Lob
@Column(name = "text", nullable = false) @Column(name = "text", nullable = false)
private String text; private String text;
@Transient @Transient
private Map<String, Object> metadata; private Map<String, Object> metadata;
/** /**
* Gets the id.
*
* @return the id * @return the id
*/ */
public Long getId() { public Long getId() {
@ -55,13 +70,17 @@ public class Comment {
} }
/** /**
* @param id the id to set * Sets the id.
*
* @param id the new id
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/** /**
* Gets the author.
*
* @return the author * @return the author
*/ */
public String getAuthor() { public String getAuthor() {
@ -69,13 +88,17 @@ public class Comment {
} }
/** /**
* @param author the author to set * Sets the author.
*
* @param author the new author
*/ */
public void setAuthor(String author) { public void setAuthor(String author) {
this.author = author; this.author = author;
} }
/** /**
* Gets the created.
*
* @return the created * @return the created
*/ */
public Instant getCreated() { public Instant getCreated() {
@ -83,13 +106,17 @@ public class Comment {
} }
/** /**
* @param created the created to set * Sets the created.
*
* @param created the new created
*/ */
public void setCreated(Instant created) { public void setCreated(Instant created) {
this.created = created; this.created = created;
} }
/** /**
* Gets the target.
*
* @return the target * @return the target
*/ */
public Long getTarget() { public Long getTarget() {
@ -97,13 +124,17 @@ public class Comment {
} }
/** /**
* @param target the target to set * Sets the target.
*
* @param target the new target
*/ */
public void setTarget(Long target) { public void setTarget(Long target) {
this.target = target; this.target = target;
} }
/** /**
* Gets the parent.
*
* @return the parent * @return the parent
*/ */
public Long getParent() { public Long getParent() {
@ -111,13 +142,17 @@ public class Comment {
} }
/** /**
* @param parent the parent to set * Sets the parent.
*
* @param parent the new parent
*/ */
public void setParent(Long parent) { public void setParent(Long parent) {
this.parent = parent; this.parent = parent;
} }
/** /**
* Gets the text.
*
* @return the text * @return the text
*/ */
public String getText() { public String getText() {
@ -125,13 +160,17 @@ public class Comment {
} }
/** /**
* @param text the text to set * Sets the text.
*
* @param text the new text
*/ */
public void setText(String text) { public void setText(String text) {
this.text = text; this.text = text;
} }
/** /**
* Gets the metadata.
*
* @return the metadata * @return the metadata
*/ */
public Map<String, Object> getMetadata() { public Map<String, Object> getMetadata() {
@ -143,7 +182,9 @@ public class Comment {
} }
/** /**
* @param metadata the metadata to set * Sets the metadata.
*
* @param metadata the metadata
*/ */
public void setMetadata(Map<String, Object> metadata) { public void setMetadata(Map<String, Object> metadata) {
this.metadata = metadata; this.metadata = metadata;

View File

@ -22,42 +22,63 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
/** /**
* @author Lurkars * The Class Entry.
*
*/ */
@Entity @Entity
@Table(name = "entries") @Table(name = "entries")
@EntityListeners({ AuditingEntityListener.class }) @EntityListeners({ AuditingEntityListener.class })
public class Entry { public class Entry {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false) @Column(name = "id", nullable = false)
private Long id; private Long id;
@Column(name = "author", nullable = false) @Column(name = "author", nullable = false)
private String author; private String author;
@Column(name = "created", nullable = false) @Column(name = "created", nullable = false)
private Instant created; private Instant created;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name = "entry_type", nullable = false) @Column(name = "entry_type", nullable = false)
private EntryType entryType; private EntryType entryType;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(name = "entry_status", nullable = false, columnDefinition = "varchar(255) default 'NORMAL'") @Column(name = "entry_status", nullable = false, columnDefinition = "varchar(255) default 'NORMAL'")
private EntryStatus entryStatus; private EntryStatus entryStatus;
@Column(name = "url") @Column(name = "url")
private String url; private String url;
@Column(name = "title", nullable = false) @Column(name = "title", nullable = false)
private String title; private String title;
@Lob @Lob
@Column(name = "text") @Column(name = "text")
private String text; private String text;
@Transient @Transient
private Double ranking; private Double ranking;
@Transient @Transient
private Map<String, Object> metadata; private Map<String, Object> metadata;
/** /**
* Gets the id.
*
* @return the id * @return the id
*/ */
public Long getId() { public Long getId() {
@ -65,13 +86,17 @@ public class Entry {
} }
/** /**
* @param id the id to set * Sets the id.
*
* @param id the new id
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/** /**
* Gets the author.
*
* @return the author * @return the author
*/ */
public String getAuthor() { public String getAuthor() {
@ -79,13 +104,17 @@ public class Entry {
} }
/** /**
* @param author the author to set * Sets the author.
*
* @param author the new author
*/ */
public void setAuthor(String author) { public void setAuthor(String author) {
this.author = author; this.author = author;
} }
/** /**
* Gets the created.
*
* @return the created * @return the created
*/ */
public Instant getCreated() { public Instant getCreated() {
@ -93,41 +122,53 @@ public class Entry {
} }
/** /**
* @param created the created to set * Sets the created.
*
* @param created the new created
*/ */
public void setCreated(Instant created) { public void setCreated(Instant created) {
this.created = created; this.created = created;
} }
/** /**
* @return the entryType * Gets the entry type.
*
* @return the entry type
*/ */
public EntryType getEntryType() { public EntryType getEntryType() {
return entryType; return entryType;
} }
/** /**
* @param entryType the entryType to set * Sets the entry type.
*
* @param entryType the new entry type
*/ */
public void setEntryType(EntryType entryType) { public void setEntryType(EntryType entryType) {
this.entryType = entryType; this.entryType = entryType;
} }
/** /**
* @return the entryStatus * Gets the entry status.
*
* @return the entry status
*/ */
public EntryStatus getEntryStatus() { public EntryStatus getEntryStatus() {
return entryStatus; return entryStatus;
} }
/** /**
* @param entryStatus the entryStatus to set * Sets the entry status.
*
* @param entryStatus the new entry status
*/ */
public void setEntryStatus(EntryStatus entryStatus) { public void setEntryStatus(EntryStatus entryStatus) {
this.entryStatus = entryStatus; this.entryStatus = entryStatus;
} }
/** /**
* Gets the url.
*
* @return the url * @return the url
*/ */
public String getUrl() { public String getUrl() {
@ -135,13 +176,17 @@ public class Entry {
} }
/** /**
* @param url the url to set * Sets the url.
*
* @param url the new url
*/ */
public void setUrl(String url) { public void setUrl(String url) {
this.url = url; this.url = url;
} }
/** /**
* Gets the title.
*
* @return the title * @return the title
*/ */
public String getTitle() { public String getTitle() {
@ -149,13 +194,17 @@ public class Entry {
} }
/** /**
* @param title the title to set * Sets the title.
*
* @param title the new title
*/ */
public void setTitle(String title) { public void setTitle(String title) {
this.title = title; this.title = title;
} }
/** /**
* Gets the text.
*
* @return the text * @return the text
*/ */
public String getText() { public String getText() {
@ -163,13 +212,17 @@ public class Entry {
} }
/** /**
* @param text the text to set * Sets the text.
*
* @param text the new text
*/ */
public void setText(String text) { public void setText(String text) {
this.text = text; this.text = text;
} }
/** /**
* Gets the ranking.
*
* @return the ranking * @return the ranking
*/ */
public Double getRanking() { public Double getRanking() {
@ -177,13 +230,17 @@ public class Entry {
} }
/** /**
* @param ranking the ranking to set * Sets the ranking.
*
* @param ranking the new ranking
*/ */
public void setRanking(Double ranking) { public void setRanking(Double ranking) {
this.ranking = ranking; this.ranking = ranking;
} }
/** /**
* Gets the metadata.
*
* @return the metadata * @return the metadata
*/ */
public Map<String, Object> getMetadata() { public Map<String, Object> getMetadata() {
@ -194,16 +251,19 @@ public class Entry {
} }
/** /**
* @param metadata the metadata to set * Sets the metadata.
*
* @param metadata the metadata
*/ */
public void setMetadata(Map<String, Object> metadata) { public void setMetadata(Map<String, Object> metadata) {
this.metadata = metadata; this.metadata = metadata;
} }
/** /**
* * From ranked entry.
* @param rankedEntry *
* @return * @param rankedEntry the ranked entry
* @return the entry
*/ */
public static Entry fromRankedEntry(RankedEntry rankedEntry) { public static Entry fromRankedEntry(RankedEntry rankedEntry) {
Entry entry = new Entry(); Entry entry = new Entry();

View File

@ -3,12 +3,17 @@
*/ */
package de.bstly.board.model; package de.bstly.board.model;
/** /**
* @author Lurkars * The Enum EntryStatus.
*
*/ */
public enum EntryStatus { public enum EntryStatus {
NORMAL, ARCHIVED, PINNED
NORMAL,
ARCHIVED,
PINNED
} }

View File

@ -3,12 +3,19 @@
*/ */
package de.bstly.board.model; package de.bstly.board.model;
/** /**
* @author Lurkars * The Enum EntryType.
*
*/ */
public enum EntryType { public enum EntryType {
DISCUSSION, INTERN, LINK, QUESTION
DISCUSSION,
INTERN,
LINK,
QUESTION
} }

View File

@ -23,44 +23,65 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
/** /**
* @author monitoring@bstly.de * The Class LocalUser.
*
*/ */
@Entity @Entity
@Table(name = "users") @Table(name = "users")
@JsonInclude(Include.NON_EMPTY) @JsonInclude(Include.NON_EMPTY)
public class LocalUser { public class LocalUser {
@Id @Id
@Column(name = "username", nullable = false) @Column(name = "username", nullable = false)
private String username; private String username;
@Column(name = "external_id", nullable = true) @Column(name = "external_id", nullable = true)
private String externalId; private String externalId;
@JsonIgnore @JsonIgnore
@Column(name = "password_hash", nullable = true) @Column(name = "password_hash", nullable = true)
private String passwordHash; private String passwordHash;
@ElementCollection @ElementCollection
@LazyCollection(LazyCollectionOption.FALSE) @LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "users_roles") @CollectionTable(name = "users_roles")
private List<String> roles; private List<String> roles;
@Lob @Lob
@Column(name = "about", nullable = true) @Column(name = "about", nullable = true)
private String about; private String about;
@Column(name = "email", nullable = true) @Column(name = "email", nullable = true)
private String email; private String email;
@Column(name = "locale", nullable = false, columnDefinition = "varchar(255) default 'en'") @Column(name = "locale", nullable = false, columnDefinition = "varchar(255) default 'en'")
private String locale; private String locale;
@Column(name = "dark_theme", columnDefinition = "boolean default false") @Column(name = "dark_theme", columnDefinition = "boolean default false")
private boolean darkTheme; private boolean darkTheme;
@ElementCollection @ElementCollection
@LazyCollection(LazyCollectionOption.FALSE) @LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "users_settings") @CollectionTable(name = "users_settings")
private Map<String, String> settings; private Map<String, String> settings;
@Transient @Transient
private Map<String, Object> metadata; private Map<String, Object> metadata;
/** /**
* Gets the username.
*
* @return the username * @return the username
*/ */
public String getUsername() { public String getUsername() {
@ -68,41 +89,53 @@ public class LocalUser {
} }
/** /**
* @param username the username to set * Sets the username.
*
* @param username the new username
*/ */
public void setUsername(String username) { public void setUsername(String username) {
this.username = username; this.username = username;
} }
/** /**
* @return the externalId * Gets the external id.
*
* @return the external id
*/ */
public String getExternalId() { public String getExternalId() {
return externalId; return externalId;
} }
/** /**
* @param externalId the externalId to set * Sets the external id.
*
* @param externalId the new external id
*/ */
public void setExternalId(String externalId) { public void setExternalId(String externalId) {
this.externalId = externalId; this.externalId = externalId;
} }
/** /**
* @return the passwordHash * Gets the password hash.
*
* @return the password hash
*/ */
public String getPasswordHash() { public String getPasswordHash() {
return passwordHash; return passwordHash;
} }
/** /**
* @param passwordHash the passwordHash to set * Sets the password hash.
*
* @param passwordHash the new password hash
*/ */
public void setPasswordHash(String passwordHash) { public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash; this.passwordHash = passwordHash;
} }
/** /**
* Gets the roles.
*
* @return the roles * @return the roles
*/ */
public List<String> getRoles() { public List<String> getRoles() {
@ -110,13 +143,17 @@ public class LocalUser {
} }
/** /**
* @param roles the roles to set * Sets the roles.
*
* @param roles the new roles
*/ */
public void setRoles(List<String> roles) { public void setRoles(List<String> roles) {
this.roles = roles; this.roles = roles;
} }
/** /**
* Gets the about.
*
* @return the about * @return the about
*/ */
public String getAbout() { public String getAbout() {
@ -124,13 +161,17 @@ public class LocalUser {
} }
/** /**
* @param about the about to set * Sets the about.
*
* @param about the new about
*/ */
public void setAbout(String about) { public void setAbout(String about) {
this.about = about; this.about = about;
} }
/** /**
* Gets the email.
*
* @return the email * @return the email
*/ */
public String getEmail() { public String getEmail() {
@ -138,13 +179,17 @@ public class LocalUser {
} }
/** /**
* @param email the email to set * Sets the email.
*
* @param email the new email
*/ */
public void setEmail(String email) { public void setEmail(String email) {
this.email = email; this.email = email;
} }
/** /**
* Gets the locale.
*
* @return the locale * @return the locale
*/ */
public String getLocale() { public String getLocale() {
@ -152,27 +197,35 @@ public class LocalUser {
} }
/** /**
* @param locale the locale to set * Sets the locale.
*
* @param locale the new locale
*/ */
public void setLocale(String locale) { public void setLocale(String locale) {
this.locale = locale; this.locale = locale;
} }
/** /**
* @return the darkTheme * Checks if is dark theme.
*
* @return true, if is dark theme
*/ */
public boolean isDarkTheme() { public boolean isDarkTheme() {
return darkTheme; return darkTheme;
} }
/** /**
* @param darkTheme the darkTheme to set * Sets the dark theme.
*
* @param darkTheme the new dark theme
*/ */
public void setDarkTheme(boolean darkTheme) { public void setDarkTheme(boolean darkTheme) {
this.darkTheme = darkTheme; this.darkTheme = darkTheme;
} }
/** /**
* Gets the settings.
*
* @return the settings * @return the settings
*/ */
public Map<String, String> getSettings() { public Map<String, String> getSettings() {
@ -180,13 +233,17 @@ public class LocalUser {
} }
/** /**
* @param settings the settings to set * Sets the settings.
*
* @param settings the settings
*/ */
public void setSettings(Map<String, String> settings) { public void setSettings(Map<String, String> settings) {
this.settings = settings; this.settings = settings;
} }
/** /**
* Gets the metadata.
*
* @return the metadata * @return the metadata
*/ */
public Map<String, Object> getMetadata() { public Map<String, Object> getMetadata() {
@ -197,7 +254,9 @@ public class LocalUser {
} }
/** /**
* @param metadata the metadata to set * Sets the metadata.
*
* @param metadata the metadata
*/ */
public void setMetadata(Map<String, Object> metadata) { public void setMetadata(Map<String, Object> metadata) {
this.metadata = metadata; this.metadata = metadata;

View File

@ -10,25 +10,34 @@ import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
/** /**
* @author monitoring@bstly.de * The Class PersistentLogin.
*
*/ */
@Entity @Entity
@Table(name = "persistent_logins") @Table(name = "persistent_logins")
public class PersistentLogin { public class PersistentLogin {
@Column(name = "username", length = 64, nullable = false) @Column(name = "username", length = 64, nullable = false)
private String username; private String username;
@Id @Id
@Column(name = "series", length = 64) @Column(name = "series", length = 64)
private String series; private String series;
@Column(name = "token", length = 64, nullable = false) @Column(name = "token", length = 64, nullable = false)
private String token; private String token;
@Column(name = "last_used", nullable = false) @Column(name = "last_used", nullable = false)
private Instant last_used; private Instant last_used;
/** /**
* Gets the username.
*
* @return the username * @return the username
*/ */
public String getUsername() { public String getUsername() {
@ -36,13 +45,17 @@ public class PersistentLogin {
} }
/** /**
* @param username the username to set * Sets the username.
*
* @param username the new username
*/ */
public void setUsername(String username) { public void setUsername(String username) {
this.username = username; this.username = username;
} }
/** /**
* Gets the series.
*
* @return the series * @return the series
*/ */
public String getSeries() { public String getSeries() {
@ -50,13 +63,17 @@ public class PersistentLogin {
} }
/** /**
* @param series the series to set * Sets the series.
*
* @param series the new series
*/ */
public void setSeries(String series) { public void setSeries(String series) {
this.series = series; this.series = series;
} }
/** /**
* Gets the token.
*
* @return the token * @return the token
*/ */
public String getToken() { public String getToken() {
@ -64,21 +81,27 @@ public class PersistentLogin {
} }
/** /**
* @param token the token to set * Sets the token.
*
* @param token the new token
*/ */
public void setToken(String token) { public void setToken(String token) {
this.token = token; this.token = token;
} }
/** /**
* @return the last_used * Gets the last used.
*
* @return the last used
*/ */
public Instant getLast_used() { public Instant getLast_used() {
return last_used; return last_used;
} }
/** /**
* @param last_used the last_used to set * Sets the last used.
*
* @param last_used the new last used
*/ */
public void setLast_used(Instant last_used) { public void setLast_used(Instant last_used) {
this.last_used = last_used; this.last_used = last_used;

View File

@ -5,27 +5,72 @@ package de.bstly.board.model;
import java.time.Instant; import java.time.Instant;
/** /**
* @author Lurkars * The Interface RankedEntry.
*
*/ */
public interface RankedEntry { public interface RankedEntry {
/**
* Gets the id.
*
* @return the id
*/
Long getId(); Long getId();
/**
* Gets the author.
*
* @return the author
*/
String getAuthor(); String getAuthor();
/**
* Gets the created.
*
* @return the created
*/
Instant getCreated(); Instant getCreated();
/**
* Gets the entry type.
*
* @return the entry type
*/
EntryType getEntry_Type(); EntryType getEntry_Type();
/**
* Gets the url.
*
* @return the url
*/
String getUrl(); String getUrl();
/**
* Gets the title.
*
* @return the title
*/
String getTitle(); String getTitle();
/**
* Gets the text.
*
* @return the text
*/
String getText(); String getText();
/**
* Gets the ranking.
*
* @return the ranking
*/
Double getRanking(); Double getRanking();
/**
* Gets the points.
*
* @return the points
*/
Long getPoints(); Long getPoints();
} }

View File

@ -3,11 +3,16 @@
*/ */
package de.bstly.board.model; package de.bstly.board.model;
/** /**
* @author Lurkars * The Enum Types.
*
*/ */
public enum Types { public enum Types {
comment, entry, user
comment,
entry,
user
} }

View File

@ -13,29 +13,40 @@ import javax.persistence.Table;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/** /**
* @author Lurkars * The Class Vote.
*
*/ */
@Entity @Entity
@Table(name = "votes") @Table(name = "votes")
@EntityListeners({ AuditingEntityListener.class }) @EntityListeners({ AuditingEntityListener.class })
public class Vote { public class Vote {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id") @Column(name = "id")
private Long id; private Long id;
@Column(name = "target", nullable = false) @Column(name = "target", nullable = false)
private Long target; private Long target;
@Column(name = "target_type", nullable = false) @Column(name = "target_type", nullable = false)
private Types targetType; private Types targetType;
@Column(name = "author", nullable = false) @Column(name = "author", nullable = false)
private String author; private String author;
@Column(name = "type", nullable = false) @Column(name = "type", nullable = false)
private VoteType type; private VoteType type;
/** /**
* Gets the id.
*
* @return the id * @return the id
*/ */
public Long getId() { public Long getId() {
@ -43,13 +54,17 @@ public class Vote {
} }
/** /**
* @param id the id to set * Sets the id.
*
* @param id the new id
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/** /**
* Gets the target.
*
* @return the target * @return the target
*/ */
public Long getTarget() { public Long getTarget() {
@ -57,27 +72,35 @@ public class Vote {
} }
/** /**
* @param target the target to set * Sets the target.
*
* @param target the new target
*/ */
public void setTarget(Long target) { public void setTarget(Long target) {
this.target = target; this.target = target;
} }
/** /**
* @return the targetType * Gets the target type.
*
* @return the target type
*/ */
public Types getTargetType() { public Types getTargetType() {
return targetType; return targetType;
} }
/** /**
* @param targetType the targetType to set * Sets the target type.
*
* @param targetType the new target type
*/ */
public void setTargetType(Types targetType) { public void setTargetType(Types targetType) {
this.targetType = targetType; this.targetType = targetType;
} }
/** /**
* Gets the author.
*
* @return the author * @return the author
*/ */
public String getAuthor() { public String getAuthor() {
@ -85,13 +108,17 @@ public class Vote {
} }
/** /**
* @param author the author to set * Sets the author.
*
* @param author the new author
*/ */
public void setAuthor(String author) { public void setAuthor(String author) {
this.author = author; this.author = author;
} }
/** /**
* Gets the type.
*
* @return the type * @return the type
*/ */
public VoteType getType() { public VoteType getType() {
@ -99,7 +126,9 @@ public class Vote {
} }
/** /**
* @param type the type to set * Sets the type.
*
* @param type the new type
*/ */
public void setType(VoteType type) { public void setType(VoteType type) {
this.type = type; this.type = type;

View File

@ -3,10 +3,15 @@
*/ */
package de.bstly.board.model; package de.bstly.board.model;
/** /**
* @author Lurkars * The Enum VoteType.
*
*/ */
public enum VoteType { public enum VoteType {
up, down
up,
down
} }

View File

@ -0,0 +1,19 @@
/**
*
*/
package de.bstly.board.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;
import de.bstly.board.model.Bookmarks;
/**
* The Interface BookmarksRepository.
*/
@Repository
public interface BookmarksRepository
extends JpaRepository<Bookmarks, String>, QuerydslPredicateExecutor<Bookmarks> {
}

View File

@ -16,28 +16,63 @@ import org.springframework.stereotype.Repository;
import de.bstly.board.model.Comment; import de.bstly.board.model.Comment;
/** /**
* * The Interface CommentRepository.
* @author monitoring@bstly.de
*
*/ */
@Repository @Repository
public interface CommentRepository public interface CommentRepository
extends JpaRepository<Comment, Long>, QuerydslPredicateExecutor<Comment> { extends JpaRepository<Comment, Long>, QuerydslPredicateExecutor<Comment> {
/**
* Find all by ranking and parent.
*
* @param target the target
* @param date the date
* @param gravity the gravity
* @return the list
*/
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent IS NULL AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent IS NULL AND comment.created < :date", nativeQuery = true) @Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent IS NULL AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent IS NULL AND comment.created < :date", nativeQuery = true)
List<Comment> findAllByRankingAndParent(@Param("target") Long target, List<Comment> findAllByRankingAndParent(@Param("target") Long target,
@Param("date") Instant date, @Param("gravity") double gravity); @Param("date") Instant date, @Param("gravity") double gravity);
/**
* Find all by ranking and parent.
*
* @param target the target
* @param parent the parent
* @param date the date
* @param gravity the gravity
* @return the list
*/
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent = :parent AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent = :parent AND comment.created < :date", nativeQuery = true) @Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent = :parent AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent = :parent AND comment.created < :date", nativeQuery = true)
List<Comment> findAllByRankingAndParent(@Param("target") Long target, List<Comment> findAllByRankingAndParent(@Param("target") Long target,
@Param("parent") Long parent, @Param("date") Instant date, @Param("parent") Long parent, @Param("date") Instant date,
@Param("gravity") double gravity); @Param("gravity") double gravity);
/**
* Find all by ranking and parent.
*
* @param target the target
* @param date the date
* @param gravity the gravity
* @param pageable the pageable
* @return the page
*/
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent IS NULL AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent IS NULL AND comment.created < :date", nativeQuery = true) @Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent IS NULL AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent IS NULL AND comment.created < :date", nativeQuery = true)
Page<Comment> findAllByRankingAndParent(@Param("target") Long target, Page<Comment> findAllByRankingAndParent(@Param("target") Long target,
@Param("date") Instant date, @Param("gravity") double gravity, Pageable pageable); @Param("date") Instant date, @Param("gravity") double gravity, Pageable pageable);
/**
* Find all by ranking and parent.
*
* @param target the target
* @param parent the parent
* @param date the date
* @param gravity the gravity
* @param pageable the pageable
* @return the page
*/
@Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent = :parent AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent = :parent AND comment.created < :date", nativeQuery = true) @Query(value = "SELECT comment.*, ranked.ranking FROM comments AS comment LEFT JOIN (SELECT comment.id, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, comment.created, :date)+2,:gravity) AS ranking FROM comments AS comment LEFT JOIN (SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 0 GROUP BY upvote.target) AS upvote ON upvote.target = comment.id LEFT JOIN (SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 GROUP BY downvote.target) AS downvote ON downvote.target = comment.id) as ranked on ranked.id = comment.id WHERE comment.target = :target AND parent = :parent AND comment.created < :date ORDER BY ranked.ranking DESC, comment.created DESC", countQuery = "SELECT count(*) FROM comments as comment WHERE comment.target = :target AND parent = :parent AND comment.created < :date", nativeQuery = true)
Page<Comment> findAllByRankingAndParent(@Param("target") Long target, Page<Comment> findAllByRankingAndParent(@Param("target") Long target,
@Param("parent") Long parent, @Param("date") Instant date, @Param("parent") Long parent, @Param("date") Instant date,

View File

@ -16,41 +16,62 @@ import org.springframework.stereotype.Repository;
import de.bstly.board.model.Entry; import de.bstly.board.model.Entry;
import de.bstly.board.model.RankedEntry; import de.bstly.board.model.RankedEntry;
/** /**
* * The Interface EntryRepository.
* @author monitoring@bstly.de
*
*/ */
@Repository @Repository
public interface EntryRepository public interface EntryRepository
extends JpaRepository<Entry, Long>, QuerydslPredicateExecutor<Entry> { extends JpaRepository<Entry, Long>, QuerydslPredicateExecutor<Entry> {
static final String UPVOTES_QUERY = "SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 1 GROUP BY upvote.target"; static final String UPVOTES_QUERY = "SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 1 GROUP BY upvote.target";
static final String DOWNVOTES_QUERY = "SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 AND downvote.target_type = 1 GROUP BY downvote.target"; static final String DOWNVOTES_QUERY = "SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 AND downvote.target_type = 1 GROUP BY downvote.target";
static final String CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity) AS ranking FROM entries AS entry LEFT JOIN (" static final String CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity) AS ranking FROM entries AS entry LEFT JOIN ("
+ UPVOTES_QUERY + UPVOTES_QUERY
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN (" + ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
+ DOWNVOTES_QUERY + DOWNVOTES_QUERY
+ ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before AND entry.entry_status = 'NORMAL' ORDER BY ranking DESC, entry.created DESC"; + ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before AND entry.entry_status = 'NORMAL' ORDER BY ranking DESC, entry.created DESC";
static final String ARCHIVE_CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity) AS ranking FROM entries AS entry LEFT JOIN (" static final String ARCHIVE_CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity) AS ranking FROM entries AS entry LEFT JOIN ("
+ UPVOTES_QUERY + UPVOTES_QUERY
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN (" + ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
+ DOWNVOTES_QUERY + DOWNVOTES_QUERY
+ ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before ORDER BY ranking DESC, entry.created DESC"; + ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before ORDER BY ranking DESC, entry.created DESC";
static final String ADDITIONAL_QUERY = "SELECT entry.*, calculation.ranking, calculation.points FROM entries AS entry LEFT JOIN (" static final String ADDITIONAL_QUERY = "SELECT entry.*, calculation.ranking, calculation.points FROM entries AS entry LEFT JOIN ("
+ CALCULATION_QUERY + CALCULATION_QUERY
+ ") as calculation on calculation.id = entry.id WHERE entry.created < :before ORDER BY calculation.ranking DESC, entry.created DESC"; + ") as calculation on calculation.id = entry.id WHERE entry.created < :before ORDER BY calculation.ranking DESC, entry.created DESC";
static final String COUNT_QUERY = "SELECT count(*) FROM entries as entry WHERE entry.created < :before"; static final String COUNT_QUERY = "SELECT count(*) FROM entries as entry WHERE entry.created < :before";
/**
* Find all by ranking.
*
* @param before the before
* @param gravity the gravity
* @param pageable the pageable
* @return the page
*/
@Query(value = CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true) @Query(value = CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
Page<RankedEntry> findAllByRanking(@Param("before") Instant before, Page<RankedEntry> findAllByRanking(@Param("before") Instant before,
@Param("gravity") double gravity, Pageable pageable); @Param("gravity") double gravity, Pageable pageable);
/**
* Find all by ranking archive.
*
* @param before the before
* @param gravity the gravity
* @param pageable the pageable
* @return the page
*/
@Query(value = ARCHIVE_CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true) @Query(value = ARCHIVE_CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
Page<RankedEntry> findAllByRankingArchive(@Param("before") Instant before, Page<RankedEntry> findAllByRankingArchive(@Param("before") Instant before,
@Param("gravity") double gravity, Pageable pageable); @Param("gravity") double gravity, Pageable pageable);

View File

@ -10,9 +10,7 @@ import org.springframework.stereotype.Repository;
import de.bstly.board.model.LocalUser; import de.bstly.board.model.LocalUser;
/** /**
* * The Interface LocalUserRepository.
* @author monitoring@bstly.de
*
*/ */
@Repository @Repository
public interface LocalUserRepository public interface LocalUserRepository

View File

@ -10,9 +10,7 @@ import org.springframework.stereotype.Repository;
import de.bstly.board.model.Vote; import de.bstly.board.model.Vote;
/** /**
* * The Interface VoteRepository.
* @author monitoring@bstly.de
*
*/ */
@Repository @Repository
public interface VoteRepository extends JpaRepository<Vote, Long>, QuerydslPredicateExecutor<Vote> { public interface VoteRepository extends JpaRepository<Vote, Long>, QuerydslPredicateExecutor<Vote> {

View File

@ -9,23 +9,27 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices; import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
/** /**
* * The Class LocalRememberMeServices.
* @author _bastler@bstly.de
*
*/ */
public class LocalRememberMeServices extends PersistentTokenBasedRememberMeServices { public class LocalRememberMeServices extends PersistentTokenBasedRememberMeServices {
/** /**
* @param key * Instantiates a new local remember me services.
* @param userDetailsService *
* @param tokenRepository * @param key the key
* @param userDetailsService the user details service
* @param tokenRepository the token repository
*/ */
public LocalRememberMeServices(String key, UserDetailsService userDetailsService, public LocalRememberMeServices(String key, UserDetailsService userDetailsService,
PersistentTokenRepository tokenRepository) { PersistentTokenRepository tokenRepository) {
super(key, userDetailsService, tokenRepository); super(key, userDetailsService, tokenRepository);
} }
/*
* @see org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices#rememberMeRequested(javax.servlet.http.HttpServletRequest, java.lang.String)
*/
/* /*
* *
* @see org.springframework.security.web.authentication.rememberme. * @see org.springframework.security.web.authentication.rememberme.

View File

@ -4,6 +4,7 @@
package de.bstly.board.security; package de.bstly.board.security;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -12,36 +13,55 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.google.common.collect.Lists;
import de.bstly.board.businesslogic.UserManager; import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.model.LocalUser; import de.bstly.board.model.LocalUser;
/** /**
* @author Lurkars * The Class OAuth2AuthenticationSuccessHandler.
*
*/ */
@Component @Component
public class OAuth2AuthenticationSuccessHandler public class OAuth2AuthenticationSuccessHandler
extends SavedRequestAwareAuthenticationSuccessHandler { extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired @Autowired
private UserManager localUserManager; private UserManager localUserManager;
private RememberMeServices rememberMeServices; private RememberMeServices rememberMeServices;
/*
* @see org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)
*/
@Override @Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException { Authentication authentication) throws IOException, ServletException {
LocalUser localUser = localUserManager.getByAuth(authentication); LocalUser localUser = localUserManager.getByAuth(authentication);
User user = new User(localUser.getUsername(), "", authentication.getAuthorities()); List<GrantedAuthority> authorities = Lists.newArrayList();
authorities.addAll(authentication.getAuthorities());
if (localUser.getRoles() != null) {
for (String role : localUser.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role));
}
}
User user = new User(localUser.getUsername(), "", authorities);
UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken( UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(
user, null, authentication.getAuthorities()); user, null, authorities);
SecurityContextHolder.getContext().setAuthentication(newAuthentication); SecurityContextHolder.getContext().setAuthentication(newAuthentication);
@ -54,6 +74,11 @@ public class OAuth2AuthenticationSuccessHandler
clearAuthenticationAttributes(request); clearAuthenticationAttributes(request);
} }
/**
* Sets the remember me services.
*
* @param rememberMeServices the new remember me services
*/
public void setRememberMeServices(RememberMeServices rememberMeServices) { public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices; this.rememberMeServices = rememberMeServices;
} }

View File

@ -25,26 +25,37 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import de.bstly.board.businesslogic.UserManager; import de.bstly.board.businesslogic.UserManager;
/** /**
* * The Class SecurityConfig.
* @author monitoring@bstly.de
*
*/ */
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter { public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired @Autowired
private UserManager localUserManager; private UserManager localUserManager;
@Autowired @Autowired
private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler; private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
@Autowired @Autowired
private DataSource dataSource; private DataSource dataSource;
@Value("${loginUrl:/login}") @Value("${loginUrl:/login}")
private String loginUrl; private String loginUrl;
@Value("${loginTargetUrl:/}") @Value("${loginTargetUrl:/}")
private String loginTargetUrl; private String loginTargetUrl;
/*
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
*/
/* /*
* *
* @see org.springframework.security.config.annotation.web.configuration. * @see org.springframework.security.config.annotation.web.configuration.
@ -87,14 +98,20 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
} }
/** /**
* * Password encoder.
* @return *
* @return the argon 2 password encoder
*/ */
@Bean(name = "passwordEncoder") @Bean(name = "passwordEncoder")
public Argon2PasswordEncoder passwordEncoder() { public Argon2PasswordEncoder passwordEncoder() {
return new Argon2PasswordEncoder(); return new Argon2PasswordEncoder();
} }
/**
* Persistent token repository.
*
* @return the persistent token repository
*/
@Bean @Bean
public PersistentTokenRepository persistentTokenRepository() { public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
@ -102,6 +119,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
return tokenRepository; return tokenRepository;
} }
/**
* Remember me services.
*
* @return the remember me services
*/
@Bean @Bean
public RememberMeServices rememberMeServices() { public RememberMeServices rememberMeServices() {
PersistentTokenBasedRememberMeServices rememberMeServices = new LocalRememberMeServices( PersistentTokenBasedRememberMeServices rememberMeServices = new LocalRememberMeServices(