initial commit
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.businesslogic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
|
||||
import de.bstly.we.businesslogic.UserDataProvider;
|
||||
import de.bstly.we.invite.model.Invite;
|
||||
import de.bstly.we.invite.model.InviteMapping;
|
||||
import de.bstly.we.invite.model.QInvite;
|
||||
import de.bstly.we.invite.repository.InviteRepository;
|
||||
import de.bstly.we.model.UserData;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class InviteManager implements UserDataProvider {
|
||||
|
||||
@Autowired
|
||||
private InviteRepository inviteRepository;
|
||||
@Autowired
|
||||
private InviteMappingManager inviteMappingManager;
|
||||
private QInvite qInvite = QInvite.invite;
|
||||
|
||||
@Value("${we.bstly.invite.codeLength:8}")
|
||||
private int codeLength;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public Invite get(Long id) {
|
||||
return inviteRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param owner
|
||||
* @return
|
||||
*/
|
||||
public List<Invite> getAllByOwner(Long owner) {
|
||||
return Lists.newArrayList(inviteRepository.findAll(qInvite.owner.eq(owner)));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param search
|
||||
* @return
|
||||
*/
|
||||
public Page<Invite> get(int page, int size, String search) {
|
||||
if (StringUtils.hasText(search)) {
|
||||
return inviteRepository.findAll(qInvite.note.containsIgnoreCase(search),
|
||||
PageRequest.of(page, size));
|
||||
}
|
||||
return inviteRepository.findAll(PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public Invite getByCode(String code) {
|
||||
return inviteRepository.findOne(qInvite.code.eq(code)).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param owner
|
||||
* @param item
|
||||
* @param page
|
||||
* @param size
|
||||
* @param sortBy
|
||||
* @param descending
|
||||
* @param search
|
||||
* @return
|
||||
*/
|
||||
public Page<Invite> getByOwner(Long owner, Integer item, int page, int size, String sortBy,
|
||||
boolean descending, String search, String redeemed) {
|
||||
PageRequest pageRequest = PageRequest.of(page, size,
|
||||
descending ? Sort.by(sortBy).descending() : Sort.by(sortBy).ascending());
|
||||
|
||||
BooleanBuilder query = new BooleanBuilder();
|
||||
query.and(qInvite.owner.eq(owner));
|
||||
|
||||
if (item != null) {
|
||||
query.and(qInvite.item.eq(item));
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(search)) {
|
||||
query.and(qInvite.note.containsIgnoreCase(search));
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(redeemed)) {
|
||||
if ("true".equals(redeemed)) {
|
||||
query.and(qInvite.redeemed.isTrue());
|
||||
} else {
|
||||
query.and(qInvite.redeemed.isFalse());
|
||||
}
|
||||
}
|
||||
|
||||
return inviteRepository.findAll(query.getValue(), pageRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param sortBy
|
||||
* @param descending
|
||||
* @return
|
||||
*/
|
||||
public Page<Invite> getOthers(Long owner, int item, int page, int size, String search,
|
||||
String redeemed) {
|
||||
|
||||
BooleanBuilder query = new BooleanBuilder();
|
||||
query.and(qInvite.owner.ne(owner));
|
||||
query.and(qInvite.item.eq(item));
|
||||
|
||||
if (StringUtils.hasText(search)) {
|
||||
query.and(qInvite.note.containsIgnoreCase(search));
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(redeemed)) {
|
||||
if ("true".equals(redeemed)) {
|
||||
query.and(qInvite.redeemed.isTrue());
|
||||
} else {
|
||||
query.and(qInvite.redeemed.isFalse());
|
||||
}
|
||||
}
|
||||
|
||||
return inviteRepository.findAll(query.getValue(), PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param invite
|
||||
* @return
|
||||
*/
|
||||
public Invite save(Invite invite) {
|
||||
if (!StringUtils.hasText(invite.getCode())) {
|
||||
invite.setCode(RandomStringUtils.random(codeLength, true, true).toUpperCase());
|
||||
while (inviteRepository.exists(qInvite.code.eq(invite.getCode()))) {
|
||||
invite.setCode(RandomStringUtils.random(codeLength, true, true).toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
InviteMapping inviteMapping = inviteMappingManager.getByItem(invite.getItem());
|
||||
Assert.notNull(inviteMapping, "No mapping for item!");
|
||||
if (StringUtils.hasLength(inviteMapping.getCodeLink())) {
|
||||
invite.setCodeLink(String.format(inviteMapping.getCodeLink(), invite.getCode()));
|
||||
} else {
|
||||
invite.setCodeLink(null);
|
||||
}
|
||||
|
||||
return inviteRepository.save(invite);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public void delete(Long id) {
|
||||
inviteRepository.deleteById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void deleteAll() {
|
||||
inviteRepository.deleteAll();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see de.bstly.we.businesslogic.UserDataProvider#getId()
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return "invites";
|
||||
}
|
||||
|
||||
/*
|
||||
* @see de.bstly.we.businesslogic.UserDataProvider#getUserData(java.lang.Long)
|
||||
*/
|
||||
@Override
|
||||
public List<UserData> getUserData(Long userId) {
|
||||
List<UserData> result = Lists.newArrayList();
|
||||
for (Invite invite : getAllByOwner(userId)) {
|
||||
result.add(invite);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see de.bstly.we.businesslogic.UserDataProvider#purgeUserData(java.lang.Long)
|
||||
*/
|
||||
@Override
|
||||
public void purgeUserData(Long userId) {
|
||||
for (Invite invite : getAllByOwner(userId)) {
|
||||
inviteRepository.delete(invite);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.businesslogic;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import de.bstly.we.invite.model.Invite;
|
||||
import de.bstly.we.invite.model.InviteMapping;
|
||||
import de.bstly.we.invite.model.QInvite;
|
||||
import de.bstly.we.invite.model.QInviteMapping;
|
||||
import de.bstly.we.invite.repository.InviteMappingRepository;
|
||||
import de.bstly.we.invite.repository.InviteRepository;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class InviteMappingManager {
|
||||
|
||||
@Autowired
|
||||
private InviteMappingRepository inviteMappingRepository;
|
||||
@Autowired
|
||||
private InviteRepository inviteRepository;
|
||||
private QInviteMapping qInviteMapping = QInviteMapping.inviteMapping;
|
||||
private QInvite qInvite = QInvite.invite;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public InviteMapping get(String quota) {
|
||||
return inviteMappingRepository.findById(quota).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public InviteMapping getByItem(int item) {
|
||||
return inviteMappingRepository.findOne(qInviteMapping.item.eq(item)).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param sortBy
|
||||
* @param descending
|
||||
* @return
|
||||
*/
|
||||
public Page<InviteMapping> get(int page, int size, String sortBy, boolean descending) {
|
||||
Sort sort = descending ? Sort.by(sortBy).descending() : Sort.by(sortBy).ascending();
|
||||
return inviteMappingRepository.findAll(PageRequest.of(page, size, sort));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param owner
|
||||
* @param room
|
||||
* @param starts
|
||||
* @param expires
|
||||
* @return
|
||||
*/
|
||||
public InviteMapping create(String quota, int item, Instant starts, Instant expires) {
|
||||
Assert.isNull(get(quota), "ivite mapping for quota already exists");
|
||||
|
||||
InviteMapping inviteMapping = new InviteMapping();
|
||||
inviteMapping.setQuota(quota);
|
||||
inviteMapping.setStarts(starts);
|
||||
inviteMapping.setExpires(expires);
|
||||
|
||||
return save(inviteMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inviteMapping
|
||||
* @return
|
||||
*/
|
||||
public InviteMapping save(InviteMapping inviteMapping) {
|
||||
|
||||
for (Invite invite : inviteRepository.findAll(qInvite.item.eq(inviteMapping.getItem()))) {
|
||||
if (StringUtils.hasText(inviteMapping.getCodeLink())) {
|
||||
String codeLink = String.format(inviteMapping.getCodeLink(), invite.getCode());
|
||||
if (!codeLink.equals(invite.getCodeLink())) {
|
||||
invite.setCodeLink(codeLink);
|
||||
inviteRepository.save(invite);
|
||||
}
|
||||
} else if (StringUtils.hasText(invite.getCodeLink())) {
|
||||
invite.setCodeLink(null);
|
||||
inviteRepository.save(invite);
|
||||
}
|
||||
}
|
||||
|
||||
return inviteMappingRepository.save(inviteMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param quota
|
||||
*/
|
||||
public void delete(String quota) {
|
||||
inviteMappingRepository.deleteById(quota);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.controller;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
|
||||
import de.bstly.we.businesslogic.PermissionManager;
|
||||
import de.bstly.we.businesslogic.Permissions;
|
||||
import de.bstly.we.businesslogic.QuotaManager;
|
||||
import de.bstly.we.businesslogic.UserManager;
|
||||
import de.bstly.we.businesslogic.UserProfileFieldManager;
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.controller.model.UserModel;
|
||||
import de.bstly.we.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.we.controller.support.RequestBodyErrors;
|
||||
import de.bstly.we.controller.validation.PasswordModelValidator;
|
||||
import de.bstly.we.controller.validation.UserModelValidator;
|
||||
import de.bstly.we.controller.validation.UserProfileFieldValidator;
|
||||
import de.bstly.we.invite.businesslogic.InviteManager;
|
||||
import de.bstly.we.invite.businesslogic.InviteMappingManager;
|
||||
import de.bstly.we.invite.model.Invite;
|
||||
import de.bstly.we.invite.model.InviteMapping;
|
||||
import de.bstly.we.model.Permission;
|
||||
import de.bstly.we.model.ProfileFieldType;
|
||||
import de.bstly.we.model.Quota;
|
||||
import de.bstly.we.model.User;
|
||||
import de.bstly.we.model.UserProfileField;
|
||||
import de.bstly.we.model.UserStatus;
|
||||
import de.bstly.we.model.Visibility;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/invites")
|
||||
public class InviteController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private InviteManager inviteManager;
|
||||
@Autowired
|
||||
private InviteMappingManager inviteMappingManager;
|
||||
@Autowired
|
||||
private UserManager userManager;
|
||||
@Autowired
|
||||
private UserProfileFieldManager userProfileFieldManager;
|
||||
@Autowired
|
||||
private PermissionManager permissionManager;
|
||||
@Autowired
|
||||
private QuotaManager quotaManager;
|
||||
@Autowired
|
||||
private PasswordModelValidator passwordModelValidator;
|
||||
@Autowired
|
||||
private UserModelValidator userModelValidator;
|
||||
@Autowired
|
||||
private UserProfileFieldValidator userProfileFieldValidator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/{code}")
|
||||
public Invite get(@PathVariable("code") String code) {
|
||||
Invite invite = inviteManager.getByCode(code);
|
||||
if (invite == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NOT_ACCEPTABLE);
|
||||
}
|
||||
|
||||
if (getCurrentUserId() == null) {
|
||||
invite.setId(null);
|
||||
invite.setItem(null);
|
||||
invite.setNote(null);
|
||||
invite.setOwner(null);
|
||||
} else if (!getCurrentUserId().equals(invite.getOwner())) {
|
||||
if (permissionManager.hasPermission(getCurrentUserId(), Permissions.ROLE_MEMBER)) {
|
||||
invite.setId(null);
|
||||
invite.setItem(null);
|
||||
if (!StringUtils.hasText(invite.getNote())) {
|
||||
invite.setNote("...");
|
||||
}
|
||||
invite.setOwner(null);
|
||||
} else {
|
||||
invite.setId(null);
|
||||
invite.setItem(null);
|
||||
invite.setNote(null);
|
||||
invite.setOwner(null);
|
||||
}
|
||||
}
|
||||
|
||||
return invite;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userModel
|
||||
*/
|
||||
@PostMapping
|
||||
public void register(@RequestBody UserModel userModel) {
|
||||
Errors errors = new RequestBodyErrors(userModel);
|
||||
Invite invite = inviteManager.getByCode(userModel.getToken());
|
||||
|
||||
if (invite == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NOT_ACCEPTABLE);
|
||||
}
|
||||
|
||||
if (invite.isRedeemed()
|
||||
|| invite.getExpires() != null && invite.getExpires().isBefore(Instant.now())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.GONE);
|
||||
}
|
||||
|
||||
boolean register = false;
|
||||
|
||||
for (Permission permission : permissionManager.getForItem(null, invite.getItem(),
|
||||
new JsonArray(), invite.getStarts())) {
|
||||
if (permission.getExpires().isAfter(Instant.now()) && !permission.isAddon()) {
|
||||
register = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!register) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
userModelValidator.validate(userModel, errors);
|
||||
passwordModelValidator.validate(userModel, errors);
|
||||
|
||||
if (userModel.getProfileFields() == null) {
|
||||
userModel.setProfileFields(Lists.newArrayList());
|
||||
}
|
||||
|
||||
if (userModel.getStatus() == null) {
|
||||
userModel.setStatus(UserStatus.NORMAL);
|
||||
}
|
||||
|
||||
for (UserProfileField userProfileField : userModel.getProfileFields()) {
|
||||
userProfileFieldValidator.validate(userProfileField, errors);
|
||||
}
|
||||
|
||||
if (errors.hasErrors()) {
|
||||
throw new EntityResponseStatusException(errors.getAllErrors(), HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
User user = userManager.create(userModel.getUsername(), userModel.getPassword(),
|
||||
userModel.getStatus());
|
||||
|
||||
for (UserProfileField userProfileField : userModel.getProfileFields()) {
|
||||
userProfileField.setTarget(user.getId());
|
||||
if (userProfileField.getType() == null) {
|
||||
userProfileField.setType(ProfileFieldType.TEXT);
|
||||
}
|
||||
|
||||
if (userProfileField.getVisibility() == null) {
|
||||
userProfileField.setVisibility(Visibility.PRIVATE);
|
||||
}
|
||||
|
||||
userProfileField = userProfileFieldManager.save(userProfileField);
|
||||
}
|
||||
|
||||
permissionManager.applyItem(user.getId(), invite.getItem(), new JsonArray(),
|
||||
invite.getStarts());
|
||||
quotaManager.applyItem(user.getId(), invite.getItem());
|
||||
|
||||
invite.setRedeemed(true);
|
||||
inviteManager.save(invite);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param quotaParameter
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping
|
||||
public Page<Invite> getInvites(@RequestParam("quota") Optional<String> quotaParameter,
|
||||
@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@RequestParam("size") Optional<Integer> sizeParameter,
|
||||
@RequestParam("sort") Optional<String> sortParamater,
|
||||
@RequestParam("desc") Optional<Boolean> descParameter,
|
||||
@RequestParam("search") Optional<String> searchParameter,
|
||||
@RequestParam("redeemed") Optional<String> redeemedParameter) {
|
||||
Integer item = null;
|
||||
if (quotaParameter.isPresent() && StringUtils.hasText(quotaParameter.get())) {
|
||||
InviteMapping inviteMapping = inviteMappingManager.get(quotaParameter.get());
|
||||
if (inviteMapping == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
item = inviteMapping.getItem();
|
||||
}
|
||||
|
||||
return inviteManager.getByOwner(getCurrentUserId(), item, pageParameter.orElse(0),
|
||||
sizeParameter.orElse(10), sortParamater.orElse("id"), descParameter.orElse(false),
|
||||
searchParameter.orElse(null), redeemedParameter.orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param quota
|
||||
* @param page
|
||||
* @param sizeParameter
|
||||
* @param searchParameter
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/{quota}/others")
|
||||
public Page<Invite> getOtherInvites(@PathVariable("quota") String quota,
|
||||
@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@RequestParam("size") Optional<Integer> sizeParameter,
|
||||
@RequestParam("search") Optional<String> searchParameter,
|
||||
@RequestParam("redeemed") Optional<String> redeemedParameter) {
|
||||
|
||||
InviteMapping inviteMapping = inviteMappingManager.get(quota);
|
||||
Quota inviteQuota = quotaManager.get(getCurrentUserId(),
|
||||
InviteMapping.QUOTA_PREFIX + quota);
|
||||
if (inviteMapping == null || inviteQuota == null || inviteQuota.getValue() < 1) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
Page<Invite> page = inviteManager.getOthers(getCurrentUserId(), inviteMapping.getItem(),
|
||||
pageParameter.orElse(0), sizeParameter.orElse(10), searchParameter.orElse(null),
|
||||
redeemedParameter.orElse(null));
|
||||
for (Invite invite : page.getContent()) {
|
||||
invite.setId(null);
|
||||
invite.setCode(null);
|
||||
invite.setCodeLink(null);
|
||||
invite.setMessage(null);
|
||||
invite.setOwner(null);
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param quota
|
||||
* @param inviteModel
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PostMapping("/{quota}")
|
||||
public Invite createInvite(@PathVariable("quota") String quota,
|
||||
@RequestBody Invite inviteModel) {
|
||||
InviteMapping inviteMapping = inviteMappingManager.get(quota);
|
||||
Quota inviteQuota = quotaManager.get(getCurrentUserId(),
|
||||
InviteMapping.QUOTA_PREFIX + quota);
|
||||
if (inviteMapping == null || inviteQuota == null || inviteQuota.getValue() < 1) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
if (!permissionManager.isFullUser(getCurrentUserId())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
Invite invite = new Invite();
|
||||
invite.setOwner(getCurrentUserId());
|
||||
invite.setStarts(inviteMapping.getStarts() != null ? inviteMapping.getStarts()
|
||||
: inviteModel.getStarts());
|
||||
invite.setExpires(inviteMapping.getExpires() != null ? inviteMapping.getExpires()
|
||||
: inviteModel.getExpires());
|
||||
invite.setItem(inviteMapping.getItem());
|
||||
|
||||
if (inviteMapping.getMessageLimit() != null && inviteMapping.getMessageLimit() > 0
|
||||
&& StringUtils.hasText(inviteModel.getMessage())
|
||||
&& inviteModel.getMessage().length() > inviteMapping.getMessageLimit()) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
invite.setMessage(inviteModel.getMessage());
|
||||
|
||||
if (!StringUtils.hasText(invite.getMessage())) {
|
||||
invite.setMessage(inviteMapping.getDefaultMessage());
|
||||
}
|
||||
|
||||
invite.setNote(inviteModel.getNote());
|
||||
invite.setRedeemed(false);
|
||||
|
||||
inviteQuota.setValue(inviteQuota.getValue() - 1);
|
||||
inviteQuota = quotaManager.update(inviteQuota);
|
||||
|
||||
return inviteManager.save(invite);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inviteModel
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PatchMapping
|
||||
public Invite updateInvite(@RequestBody Invite inviteModel) {
|
||||
if (inviteModel.getId() == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
Invite invite = inviteManager.get(inviteModel.getId());
|
||||
|
||||
if (invite == null || !invite.getOwner().equals(getCurrentUserId())
|
||||
|| !permissionManager.isFullUser(getCurrentUserId())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
invite.setMessage(inviteModel.getMessage());
|
||||
invite.setNote(inviteModel.getNote());
|
||||
|
||||
return inviteManager.save(invite);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.Errors;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.we.controller.support.RequestBodyErrors;
|
||||
import de.bstly.we.invite.businesslogic.InviteManager;
|
||||
import de.bstly.we.invite.businesslogic.InviteMappingManager;
|
||||
import de.bstly.we.invite.model.Invite;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/invites/manage")
|
||||
public class InviteManagingController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private InviteManager inviteManager;
|
||||
@Autowired
|
||||
private InviteMappingManager inviteMappingManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@GetMapping
|
||||
public Page<Invite> getInvites(@RequestParam("page") Optional<Integer> page,
|
||||
@RequestParam("size") Optional<Integer> size,
|
||||
@RequestParam("search") Optional<String> search) {
|
||||
return inviteManager.get(page.orElse(0), size.orElse(10), search.orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userModel
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping
|
||||
public Invite createOrUpdate(@RequestBody Invite invite) {
|
||||
if (invite.getItem() == null || inviteMappingManager.getByItem(invite.getItem()) == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
return inviteManager.save(invite);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param invites
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping("/list")
|
||||
public List<Invite> createOrUpdateList(@RequestBody List<Invite> invites) {
|
||||
List<Invite> result = Lists.newArrayList();
|
||||
for (Invite invite : invites) {
|
||||
Errors errors = new RequestBodyErrors(invite);
|
||||
if (errors.hasErrors()) {
|
||||
throw new EntityResponseStatusException(errors.getAllErrors(), HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
result.add(inviteManager.save(invite));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@DeleteMapping("/{id}")
|
||||
public void delete(@PathVariable("id") Long id) {
|
||||
if (inviteManager.get(id) == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
inviteManager.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@DeleteMapping
|
||||
public void deleteAll() {
|
||||
inviteManager.deleteAll();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.Errors;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.we.controller.support.RequestBodyErrors;
|
||||
import de.bstly.we.invite.businesslogic.InviteMappingManager;
|
||||
import de.bstly.we.invite.model.InviteMapping;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/invites/mappings")
|
||||
public class InviteMappingController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private InviteMappingManager inviteMappingManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pageParameter
|
||||
* @param sizeParameter
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@GetMapping
|
||||
public Page<InviteMapping> getInviteMappings(
|
||||
@RequestParam("page") Optional<Integer> pageParameter,
|
||||
@RequestParam("size") Optional<Integer> sizeParameter) {
|
||||
return inviteMappingManager.get(pageParameter.orElse(0), sizeParameter.orElse(10), "quota",
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userModel
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping
|
||||
public InviteMapping createOrUpdate(@RequestBody InviteMapping inviteMapping) {
|
||||
return inviteMappingManager.save(inviteMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inviteMappings
|
||||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping("/list")
|
||||
public List<InviteMapping> createOrUpdateList(@RequestBody List<InviteMapping> inviteMappings) {
|
||||
List<InviteMapping> result = Lists.newArrayList();
|
||||
for (InviteMapping inviteMapping : inviteMappings) {
|
||||
Errors errors = new RequestBodyErrors(inviteMapping);
|
||||
if (errors.hasErrors()) {
|
||||
throw new EntityResponseStatusException(errors.getAllErrors(), HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
result.add(inviteMappingManager.save(inviteMapping));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param quota
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@DeleteMapping("/{quota}")
|
||||
public void delete(@PathVariable("quota") String quota) {
|
||||
if (inviteMappingManager.get(quota) == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
|
||||
}
|
||||
inviteMappingManager.delete(quota);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import de.bstly.we.model.UserData;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "invites")
|
||||
public class Invite implements UserData {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
private Long owner;
|
||||
private String code;
|
||||
private Integer item;
|
||||
private Instant starts;
|
||||
private Instant expires;
|
||||
@Lob
|
||||
private String message;
|
||||
private String note;
|
||||
private boolean redeemed;
|
||||
private String codeLink;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the owner
|
||||
*/
|
||||
public Long getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param owner the owner to set
|
||||
*/
|
||||
public void setOwner(Long owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the code
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param code the code to set
|
||||
*/
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the item
|
||||
*/
|
||||
public Integer getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param item the item to set
|
||||
*/
|
||||
public void setItem(Integer item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the starts
|
||||
*/
|
||||
public Instant getStarts() {
|
||||
return starts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param starts the starts to set
|
||||
*/
|
||||
public void setStarts(Instant starts) {
|
||||
this.starts = starts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expires
|
||||
*/
|
||||
public Instant getExpires() {
|
||||
return expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expires the expires to set
|
||||
*/
|
||||
public void setExpires(Instant expires) {
|
||||
this.expires = expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message the message to set
|
||||
*/
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the note
|
||||
*/
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param note the note to set
|
||||
*/
|
||||
public void setNote(String note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the redeemed
|
||||
*/
|
||||
public boolean isRedeemed() {
|
||||
return redeemed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redeemed the redeemed to set
|
||||
*/
|
||||
public void setRedeemed(boolean redeemed) {
|
||||
this.redeemed = redeemed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the codeLink
|
||||
*/
|
||||
public String getCodeLink() {
|
||||
return codeLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param codeLink the codeLink to set
|
||||
*/
|
||||
public void setCodeLink(String codeLink) {
|
||||
this.codeLink = codeLink;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "invite_mapping")
|
||||
public class InviteMapping {
|
||||
|
||||
public static final String QUOTA_PREFIX = "invite_";
|
||||
|
||||
@Id
|
||||
private String quota;
|
||||
private Integer item;
|
||||
private Instant starts;
|
||||
private Instant expires;
|
||||
@Column(name = "message_limit")
|
||||
private Integer messageLimit;
|
||||
private String codeLink;
|
||||
private String defaultMessage;
|
||||
|
||||
/**
|
||||
* @return the quota
|
||||
*/
|
||||
public String getQuota() {
|
||||
return quota;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param quota the quota to set
|
||||
*/
|
||||
public void setQuota(String quota) {
|
||||
this.quota = quota;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the item
|
||||
*/
|
||||
public Integer getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param item the item to set
|
||||
*/
|
||||
public void setItem(Integer item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the starts
|
||||
*/
|
||||
public Instant getStarts() {
|
||||
return starts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param starts the starts to set
|
||||
*/
|
||||
public void setStarts(Instant starts) {
|
||||
this.starts = starts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expires
|
||||
*/
|
||||
public Instant getExpires() {
|
||||
return expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expires the expires to set
|
||||
*/
|
||||
public void setExpires(Instant expires) {
|
||||
this.expires = expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the messageLimit
|
||||
*/
|
||||
public Integer getMessageLimit() {
|
||||
return messageLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param messageLimit the messageLimit to set
|
||||
*/
|
||||
public void setMessageLimit(Integer messageLimit) {
|
||||
this.messageLimit = messageLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the codeLink
|
||||
*/
|
||||
public String getCodeLink() {
|
||||
return codeLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param codeLink the codeLink to set
|
||||
*/
|
||||
public void setCodeLink(String codeLink) {
|
||||
this.codeLink = codeLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the defaultMessage
|
||||
*/
|
||||
public String getDefaultMessage() {
|
||||
return defaultMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param defaultMessage the defaultMessage to set
|
||||
*/
|
||||
public void setDefaultMessage(String defaultMessage) {
|
||||
this.defaultMessage = defaultMessage;
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.bstly.we.invite.model.InviteMapping;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public interface InviteMappingRepository
|
||||
extends JpaRepository<InviteMapping, String>, QuerydslPredicateExecutor<InviteMapping> {
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.invite.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.bstly.we.invite.model.Invite;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author _bastler@bstly.de
|
||||
*
|
||||
*/
|
||||
@Repository
|
||||
public interface InviteRepository
|
||||
extends JpaRepository<Invite, Long>, QuerydslPredicateExecutor<Invite> {
|
||||
}
|
||||
Reference in New Issue
Block a user