package de.asideas.crowdsource.controller; import de.asideas.crowdsource.domain.exception.InvalidRequestException; import de.asideas.crowdsource.domain.exception.ResourceNotFoundException; import de.asideas.crowdsource.domain.model.FinancingRoundEntity; import de.asideas.crowdsource.domain.model.UserEntity; import de.asideas.crowdsource.presentation.user.User; import de.asideas.crowdsource.presentation.user.UserActivation; import de.asideas.crowdsource.presentation.user.UserRegistration; import de.asideas.crowdsource.repository.FinancingRoundRepository; import de.asideas.crowdsource.repository.UserRepository; import de.asideas.crowdsource.security.Roles; import de.asideas.crowdsource.service.UserService; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.annotation.Secured; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; import java.security.Principal; import static org.apache.commons.lang3.StringUtils.isBlank; @RestController @RequestMapping(value = "/user") public class UserController { private static final Logger LOG = LoggerFactory.getLogger(UserController.class); @Autowired private UserRepository userRepository; @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserService userService; @Autowired private FinancingRoundRepository financingRoundRepository; @ResponseStatus(HttpStatus.CREATED) @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public void registerUser(@RequestBody @Valid UserRegistration userRegistration) { final String email = userRegistration.getEmail().toLowerCase(); UserEntity userEntity = userRepository.findByEmail(email); if (userEntity == null) { userEntity = new UserEntity(email); } else { LOG.debug("A user with the address {} already exists, assigning a new activation token", email); } userService.assignActivationTokenForRegistration(userEntity); } @RequestMapping(value = "/{email}/activation", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public void activateUser( @PathVariable String email, @RequestBody @Valid UserActivation userActivation) { email = email.toLowerCase(); UserEntity userEntity = userRepository.findByEmail(email); if (userEntity == null) { LOG.debug("userentity with id {} does not exist and can therefore not be activated.", email); throw new ResourceNotFoundException(); } // The activation token may be set to non blank when using password recovery. // In this case, the user is still activated but has a token set. if (isBlank(userEntity.getActivationToken()) && userEntity.isActivated()) { LOG.debug("user {} is already activated", userEntity); throw InvalidRequestException.userAlreadyActivated(); } if (isBlank(userEntity.getActivationToken()) || !userEntity.getActivationToken().equals(userActivation.getActivationToken())) { LOG.debug("token mismatch on activation request for user with email: {} (was {}, expected: {})", email, userActivation.getActivationToken(), userEntity.getActivationToken()); throw InvalidRequestException.activationTokenInvalid(); } userEntity.setActivated(true); userEntity.setActivationToken(""); userEntity.setPassword(passwordEncoder.encode(userActivation.getPassword())); userRepository.save(userEntity); LOG.debug("User activated: {}", userEntity); } @ResponseStatus(HttpStatus.NO_CONTENT) @RequestMapping(value = "/{email}/password-recovery", method = RequestMethod.GET) public void recoverPassword(@PathVariable String email) { email = email.toLowerCase(); UserEntity userEntity = userRepository.findByEmail(email); if (userEntity == null) { LOG.debug("userentity with id {} does not exist and a password can therefore not be recovered.", email); throw new ResourceNotFoundException(); } userService.assignActivationTokenForPasswordRecovery(userEntity); } @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/current", method = RequestMethod.GET) public User getCurrentUser(Principal principal) { UserEntity userEntity = userService.getUserByEmail(principal.getName()); FinancingRoundEntity currentFinancingRound = financingRoundRepository.findActive(DateTime.now()); if (currentFinancingRound == null) { // if there is no active financing round, the budget of the user should be 0 // but we have no scheduler that resets the budget of every user to 0 when the financing round ends userEntity.setBudget(0); } return new User(userEntity); } }