package rocks.zipcode.io.web.rest; import rocks.zipcode.io.config.Constants; import rocks.zipcode.io.domain.User; import rocks.zipcode.io.repository.UserRepository; import rocks.zipcode.io.security.AuthoritiesConstants; import rocks.zipcode.io.service.MailService; import rocks.zipcode.io.service.UserService; import rocks.zipcode.io.service.dto.UserDTO; import rocks.zipcode.io.web.rest.errors.BadRequestAlertException; import rocks.zipcode.io.web.rest.errors.EmailAlreadyUsedException; import rocks.zipcode.io.web.rest.errors.LoginAlreadyUsedException; import rocks.zipcode.io.web.rest.util.HeaderUtil; import rocks.zipcode.io.web.rest.util.PaginationUtil; import com.codahale.metrics.annotation.Timed; import io.github.jhipster.web.util.ResponseUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.net.URI; import java.net.URISyntaxException; import java.util.*; /** * REST controller for managing users. *

* This class accesses the User entity, and needs to fetch its collection of authorities. *

* For a normal use-case, it would be better to have an eager relationship between User and Authority, * and send everything to the client side: there would be no View Model and DTO, a lot less code, and an outer-join * which would be good for performance. *

* We use a View Model and a DTO for 3 reasons: *

*

* Another option would be to have a specific JPA entity graph to handle this case. */ @RestController @RequestMapping("/api") public class UserResource { private final Logger log = LoggerFactory.getLogger(UserResource.class); private final UserService userService; private final UserRepository userRepository; private final MailService mailService; public UserResource(UserService userService, UserRepository userRepository, MailService mailService) { this.userService = userService; this.userRepository = userRepository; this.mailService = mailService; } /** * POST /users : Creates a new user. *

* Creates a new user if the login and email are not already used, and sends an * mail with an activation link. * The user needs to be activated on creation. * * @param userDTO the user to create * @return the ResponseEntity with status 201 (Created) and with body the new user, or with status 400 (Bad Request) if the login or email is already in use * @throws URISyntaxException if the Location URI syntax is incorrect * @throws BadRequestAlertException 400 (Bad Request) if the login or email is already in use */ @PostMapping("/users") @Timed @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")") public ResponseEntity createUser(@Valid @RequestBody UserDTO userDTO) throws URISyntaxException { log.debug("REST request to save User : {}", userDTO); if (userDTO.getId() != null) { throw new BadRequestAlertException("A new user cannot already have an ID", "userManagement", "idexists"); // Lowercase the user login before comparing with database } else if (userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).isPresent()) { throw new LoginAlreadyUsedException(); } else if (userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).isPresent()) { throw new EmailAlreadyUsedException(); } else { User newUser = userService.createUser(userDTO); mailService.sendCreationEmail(newUser); return ResponseEntity.created(new URI("/api/users/" + newUser.getLogin())) .headers(HeaderUtil.createAlert( "userManagement.created", newUser.getLogin())) .body(newUser); } } /** * PUT /users : Updates an existing User. * * @param userDTO the user to update * @return the ResponseEntity with status 200 (OK) and with body the updated user * @throws EmailAlreadyUsedException 400 (Bad Request) if the email is already in use * @throws LoginAlreadyUsedException 400 (Bad Request) if the login is already in use */ @PutMapping("/users") @Timed @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")") public ResponseEntity updateUser(@Valid @RequestBody UserDTO userDTO) { log.debug("REST request to update User : {}", userDTO); Optional existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()); if (existingUser.isPresent() && (!existingUser.get().getId().equals(userDTO.getId()))) { throw new EmailAlreadyUsedException(); } existingUser = userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()); if (existingUser.isPresent() && (!existingUser.get().getId().equals(userDTO.getId()))) { throw new LoginAlreadyUsedException(); } Optional updatedUser = userService.updateUser(userDTO); return ResponseUtil.wrapOrNotFound(updatedUser, HeaderUtil.createAlert("userManagement.updated", userDTO.getLogin())); } /** * GET /users : get all users. * * @param pageable the pagination information * @return the ResponseEntity with status 200 (OK) and with body all users */ @GetMapping("/users") @Timed public ResponseEntity> getAllUsers(Pageable pageable) { final Page page = userService.getAllManagedUsers(pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/users"); return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); } /** * @return a string list of the all of the roles */ @GetMapping("/users/authorities") @Timed @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")") public List getAuthorities() { return userService.getAuthorities(); } /** * GET /users/:login : get the "login" user. * * @param login the login of the user to find * @return the ResponseEntity with status 200 (OK) and with body the "login" user, or with status 404 (Not Found) */ @GetMapping("/users/{login:" + Constants.LOGIN_REGEX + "}") @Timed public ResponseEntity getUser(@PathVariable String login) { log.debug("REST request to get User : {}", login); return ResponseUtil.wrapOrNotFound( userService.getUserWithAuthoritiesByLogin(login) .map(UserDTO::new)); } /** * DELETE /users/:login : delete the "login" User. * * @param login the login of the user to delete * @return the ResponseEntity with status 200 (OK) */ @DeleteMapping("/users/{login:" + Constants.LOGIN_REGEX + "}") @Timed @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")") public ResponseEntity deleteUser(@PathVariable String login) { log.debug("REST request to delete User: {}", login); userService.deleteUser(login); return ResponseEntity.ok().headers(HeaderUtil.createAlert( "userManagement.deleted", login)).build(); } }