Skip to content
Snippets Groups Projects

Implementer filhåndtering for profilbilder

Merged Jakob Karevold Grønhaug requested to merge profilbilder into main
3 files
+ 160
3
Compare changes
  • Side-by-side
  • Inline
Files
3
 
package edu.ntnu.idatt210602.matsvinnbackend.controller;
 
 
import java.io.IOException;
 
import java.nio.file.Files;
 
import java.nio.file.Paths;
 
import java.nio.file.StandardCopyOption;
 
 
import org.springframework.beans.factory.annotation.Autowired;
 
import org.springframework.beans.factory.annotation.Value;
 
import org.springframework.core.io.Resource;
 
import org.springframework.core.io.UrlResource;
 
import org.springframework.http.HttpHeaders;
 
import org.springframework.http.HttpStatus;
 
import org.springframework.http.MediaType;
 
import org.springframework.http.ResponseEntity;
 
import org.springframework.security.core.context.SecurityContextHolder;
 
import org.springframework.stereotype.Controller;
 
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.RequestMapping;
 
import org.springframework.web.bind.annotation.RequestParam;
 
import org.springframework.web.multipart.MultipartFile;
 
import org.springframework.web.server.ResponseStatusException;
 
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
 
 
import org.slf4j.Logger;
 
import org.slf4j.LoggerFactory;
 
import edu.ntnu.idatt210602.matsvinnbackend.model.Account;
 
import edu.ntnu.idatt210602.matsvinnbackend.model.Profile;
 
import edu.ntnu.idatt210602.matsvinnbackend.repo.AccountRepository;
 
import edu.ntnu.idatt210602.matsvinnbackend.repo.ProfileRepository;
 
 
import java.nio.file.Path;
 
 
@Controller
 
@RequestMapping(path = "/img")
 
public class FileController {
 
 
Logger logger = LoggerFactory.getLogger(ProfileController.class);
 
 
@Value("${filebucket.path}")
 
String basePath;
 
 
@Autowired
 
AccountRepository accountRepo;
 
 
@Autowired
 
ProfileRepository profileRepo;
 
 
@PostMapping("")
 
public ResponseEntity<String> uploadProfilePicture(@RequestParam("file") MultipartFile file,
 
@RequestParam("profileId") Integer profileId) {
 
String authenticatedUsername = SecurityContextHolder.getContext().getAuthentication().getName();
 
Account loggedInAccount = accountRepo.findByEmail(authenticatedUsername).orElseThrow();
 
 
// Ensure that the provided profile ID is valid
 
Profile profile = profileRepo.findById(profileId).orElseThrow(() -> {
 
return new ResponseStatusException(HttpStatus.BAD_REQUEST);
 
});
 
 
// Ensure that the profile is part of the authenticated account
 
if (!loggedInAccount.getId().equals(profile.getAccountId())) {
 
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
 
}
 
 
// Allow only JPEG images
 
if (!file.getContentType().equals(MediaType.IMAGE_JPEG_VALUE)) {
 
throw new ResponseStatusException(HttpStatus.UNSUPPORTED_MEDIA_TYPE);
 
}
 
 
// Only allow images up to 512 kilobytes
 
if (file.getSize() > 524288) {
 
throw new ResponseStatusException(HttpStatus.PAYLOAD_TOO_LARGE);
 
}
 
 
// Use unique profile ID as filename for 1:1 mapping between profiles and images
 
String filename = String.format("%d.jpeg", profileId);
 
Path path = Paths.get(basePath, filename);
 
 
try {
 
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
 
} catch (IOException e) {
 
logger.error("Unable to write uploaded file to storage!");
 
}
 
 
String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
 
.path("/img/")
 
.path(profileId.toString())
 
.toUriString();
 
 
return ResponseEntity.ok(fileDownloadUri);
 
}
 
 
@GetMapping("/{profileId:.+}")
 
public ResponseEntity<Resource> get(@PathVariable Integer profileId) {
 
String authenticatedUsername = SecurityContextHolder.getContext().getAuthentication().getName();
 
Account loggedInAccount = accountRepo.findByEmail(authenticatedUsername).orElseThrow();
 
 
// Ensure that the provided profile ID is valid
 
Profile profile = profileRepo.findById(profileId).orElseThrow(() -> {
 
return new ResponseStatusException(HttpStatus.BAD_REQUEST);
 
});
 
 
// Ensure that the profile is part of the authenticated account
 
if (!loggedInAccount.getId().equals(profile.getAccountId())) {
 
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
 
}
 
 
Path path = Paths.get(basePath, String.format("%d.jpeg", profileId));
 
 
if (!path.toFile().exists()) {
 
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
 
}
 
 
Resource file = null;
 
 
try {
 
file = new UrlResource(path.toUri());
 
} catch (Exception e) {
 
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
 
}
 
 
return ResponseEntity.ok()
 
.contentType(MediaType.IMAGE_JPEG)
 
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
 
.body(file);
 
}
 
 
@DeleteMapping("")
 
public ResponseEntity<Void> deleteImage(@RequestParam("profileId") Integer profileId) {
 
String authenticatedUsername = SecurityContextHolder.getContext().getAuthentication().getName();
 
Account loggedInAccount = accountRepo.findByEmail(authenticatedUsername).orElseThrow();
 
 
// Ensure that the provided profile ID is valid
 
Profile profile = profileRepo.findById(profileId).orElseThrow(() -> {
 
return new ResponseStatusException(HttpStatus.BAD_REQUEST);
 
});
 
 
// Ensure that the profile is part of the authenticated account
 
if (!loggedInAccount.getId().equals(profile.getAccountId())) {
 
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
 
}
 
 
Path path = Paths.get(basePath, String.format("%d.jpeg", profileId));
 
 
if (path.toFile().delete()) {
 
return ResponseEntity.ok().build();
 
} else {
 
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR);
 
}
 
}
 
}
 
\ No newline at end of file
Loading