review-api/src/main/java/com/guams/review/controller/AuthorController.java

145 lines
6.5 KiB
Java

package com.guams.review.controller;
import com.guams.review.configuration.JwtTokenUtil;
import com.guams.review.exception.AlreadyExistsException;
import com.guams.review.exception.UnauthorizedExecption;
import com.guams.review.exception.InvalidNameOrPasswordException;
import com.guams.review.exception.NotFoundException;
import com.guams.review.model.AuthorRepository;
import com.guams.review.model.dao.Author;
import com.guams.review.model.dao.AuthorToken;
import com.guams.review.model.dao.Post;
import com.guams.review.service.AuthorService;
import com.guams.review.service.mapper.Mapper;
import com.guams.review.service.mapper.ReturnableAuthor;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping(path = "api/authors")
@RequiredArgsConstructor
public class AuthorController {
private final PasswordEncoder passwordEncoder;
private final AuthenticationManager authenticationManager;
private final AuthorService authorService;
private final JwtTokenUtil jwtTokenUtil;
private final AuthorRepository authorRepository;
private final Mapper mapper;
@GetMapping
public List<ReturnableAuthor> getUsers() {
return authorService.list();
}
@GetMapping("/{id}")
public ReturnableAuthor findUser(@PathVariable UUID id) {
Author author = authorService.findById(id).orElseThrow(() -> new NotFoundException("Author not found"));
return mapper.mapAuthor(author);
}
@PutMapping("/{id}")
public ReturnableAuthor updateUser(@PathVariable UUID id, @RequestBody Author updatedAuthor, Authentication authentication) {
Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id);
if (passwordEncoder.matches(updatedAuthor.getPassword(), authorToUpdate.getPassword())) {
return authorService.insert(updatedAuthor
.setId(authorToUpdate.getId())
.setRole(authorToUpdate.getRole())
.setPassword(authorToUpdate.getPassword()));
} else {
throw new UnauthorizedExecption("You are not authorized to update this author");
}
}
// @PutMapping("/{id}/password")
// public void changePassword(@PathVariable UUID id, @RequestBody Author updatedAuthor, Authentication authentication) {
// Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id);
// if (passwordEncoder.matches(updatedAuthor.getPassword(), authorToUpdate.getPassword())) {}
// }
@PutMapping(value = "{id}/avatar", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public Author updateUserAvatar(@PathVariable UUID id, @RequestPart MultipartFile avatar, Authentication authentication) throws IOException {
Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id);
ReturnableAuthor authorToReturn = authorService.insert(authorToUpdate.setProfilePicture(avatar.getBytes()));
return new Author()
.setId(authorToReturn.getId())
.setName(authorToReturn.getName())
.setProfilePicture(null)
.setRole(authorToReturn.getRole())
.setPassword("");
}
@GetMapping("/{id}/avatar")
public byte[] getProfilePicture(@PathVariable UUID id) {
Author author = authorService.findById(id).orElseThrow(() -> new NotFoundException("Author not found"));
return author.getProfilePicture();
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable UUID id, Authentication authentication) {
Author authorToDelete = authorService.verifyIfUserIsAuthorized(authentication, id);
authorService.delete(authorToDelete);
}
@PutMapping("/{id}/posts")
public void updateUserPosts(@PathVariable("id") UUID authorId, @RequestBody Long postId, Authentication authentication) {
Author author = authorService.verifyIfUserIsAuthorized(authentication, authorId);
authorService.insertPublications(author.getId(), postId);
}
@GetMapping("/{id}/posts")
public List<Post> getUserPosts(@PathVariable UUID id) {
Author author = authorService.findById(id).orElseThrow(() -> new NotFoundException("Author not found"));
return authorService.listPublicationOfAuthor(author.getId());
}
@PostMapping("/login")
public AuthorToken authorLogin(@RequestBody Author author) {
try {
Author concernedAuthor = authorService.findByName(author.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(concernedAuthor.getId(), author.getPassword())
);
String token = jwtTokenUtil.generateToken(concernedAuthor.getId().toString());
return new AuthorToken().setToken(token);
} catch (Exception e) {
throw new InvalidNameOrPasswordException(e.getMessage());
}
}
@PostMapping("/register")
public ResponseEntity<Author> authorRegister(@RequestBody Author author) {
Assert.isNull(author.getId(), "Author id must be null");
if (authorService.findByName(author.getName()).isPresent()) {
throw new AlreadyExistsException("Author already exists");
}
author.setPassword(passwordEncoder.encode(author.getPassword()));
return new ResponseEntity<>(authorRepository.save(author.setRole("READER")).setPassword(""), HttpStatus.CREATED);
}
@GetMapping(value = "/me", produces = "application/json")
public Author getAuthenticatedUser(Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) {
throw new UnauthorizedExecption("You are not authorized to access this resource");
}
Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
return author.setPassword("").setProfilePicture(null);
}
}