refactor pour intégrer l'architecture 3-tiers

This commit is contained in:
2025-12-02 23:21:44 +01:00
parent f0e20be396
commit 6a3569029d
41 changed files with 530 additions and 226 deletions

View File

@@ -1,49 +1,46 @@
package local.epul4a.fotosharing.controller;
import local.epul4a.fotosharing.model.Partage;
import local.epul4a.fotosharing.model.Photo;
import local.epul4a.fotosharing.model.Utilisateur;
import local.epul4a.fotosharing.repository.PartageRepository;
import local.epul4a.fotosharing.repository.PhotoRepository;
import local.epul4a.fotosharing.repository.UtilisateurRepository;
import local.epul4a.fotosharing.security.CustomUserDetails;
import local.epul4a.fotosharing.dto.CommentaireDTO;
import local.epul4a.fotosharing.dto.PartageDTO;
import local.epul4a.fotosharing.dto.PhotoDTO;
import local.epul4a.fotosharing.service.CommentaireService;
import local.epul4a.fotosharing.service.PartageService;
import local.epul4a.fotosharing.service.PhotoService;
import local.epul4a.fotosharing.service.UtilisateurService;
import org.springframework.core.io.Resource;
import org.springframework.core.io.PathResource;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@Controller
public class PhotoController {
private final PhotoService photoService;
private final PhotoRepository photoRepository;
private final CommentaireService commentaireService;
private final UtilisateurRepository utilisateurRepository;
private final PartageRepository partageRepository;
private final PartageService partageService;
private final UtilisateurService utilisateurService;
public PhotoController(PhotoService photoService, PhotoRepository photoRepository, CommentaireService commentaireService, UtilisateurRepository utilisateurRepository, PartageRepository partageRepository) {
public PhotoController(
PhotoService photoService,
CommentaireService commentaireService,
PartageService partageService,
UtilisateurService utilisateurService
) {
this.photoService = photoService;
this.photoRepository = photoRepository;
this.commentaireService = commentaireService;
this.utilisateurRepository = utilisateurRepository;
this.partageRepository = partageRepository;
this.partageService = partageService;
this.utilisateurService = utilisateurService;
}
/* ========================== UPLOAD ========================== */
@GetMapping("/upload")
public String uploadForm() {
return "upload";
@@ -52,147 +49,142 @@ public class PhotoController {
@PostMapping("/upload")
public String doUpload(@RequestParam("file") MultipartFile file,
@RequestParam(value = "visibilite", defaultValue = "PRIVATE") String visibilite,
Authentication authentication,
Authentication auth,
Model model) {
try {
String email = authentication.getName(); // l'email de l'utilisateur connecté
Photo p = photoService.store(file, visibilite, email);
model.addAttribute("message", "Upload OK : " + p.getId());
return "redirect:/";
} catch (Exception e) {
model.addAttribute("error", e.getMessage());
photoService.store(file, visibilite, auth.getName());
return "redirect:/mes-photos";
} catch (Exception ex) {
model.addAttribute("error", ex.getMessage());
return "upload";
}
}
/* ========================== RAW IMAGE ========================== */
@GetMapping("/photo/{id}/raw")
public ResponseEntity<Resource> rawPhoto(@PathVariable("id") Long id) {
Photo photo = photoRepository.findById(id).orElse(null);
if (photo == null) {
public ResponseEntity<Resource> rawPhoto(@PathVariable Long id) {
PhotoDTO photo = photoService.getPhotoById(id);
if (photo == null)
return ResponseEntity.notFound().build();
}
Path p = photoService.loadAsPath(photo.getUuidFichier());
Resource r = new PathResource(p);
if (!r.exists()) {
Resource r = photoService.loadAsResource(photo.getUuidFichier());
if (!r.exists())
return ResponseEntity.notFound().build();
}
String contentType = "application/octet-stream";
try {
contentType = Files.probeContentType(p);
} catch (Exception ignored) {
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION,
"inline; filename=\"" + photo.getNomFichierOriginal() + "\"")
.contentType(MediaType.IMAGE_JPEG) // simplifiable, ou détecté dans service
.body(r);
}
/* ========================== MES PHOTOS ========================== */
@GetMapping("/mes-photos")
public String mesPhotos(
@RequestParam(name = "pagePrivees", defaultValue = "0") int pagePrivees,
@RequestParam(name = "pagePubliques", defaultValue = "0") int pagePubliques,
@RequestParam(name = "pagePartagees", defaultValue = "0") int pagePartagees,
@RequestParam(name = "pageMesPartagees", defaultValue = "0") int pageMesPartagees,
Model model,
Authentication auth
) {
String email = auth.getName();
// Chaque liste utilise sa propre pagination
model.addAttribute("photosPrivees", photoService.listPrivatePhotos(email, pagePrivees, 12));
model.addAttribute("photosPubliques", photoService.listPublicPhotos(email, pagePubliques, 12));
model.addAttribute("photosPartagees", photoService.listSharedWith(email, pagePartagees, 12));
model.addAttribute("mesPhotosPartagees", photoService.listSharedPhotos(email, pageMesPartagees, 12));
@RequestParam(defaultValue = "0") int pagePrivees,
@RequestParam(defaultValue = "0") int pagePubliques,
@RequestParam(defaultValue = "0") int pagePartagees,
@RequestParam(defaultValue = "0") int pageMesPartagees,
Authentication auth, Model model) {
String email = auth.getName();
model.addAttribute("photosPrivees",
photoService.listPrivatePhotos(email, pagePrivees, 12));
model.addAttribute("photosPubliques",
photoService.listPublicPhotos(email, pagePubliques, 12));
model.addAttribute("photosPartagees",
photoService.listSharedWith(email, pagePartagees, 12));
model.addAttribute("mesPhotosPartagees",
photoService.listSharedPhotos(email, pageMesPartagees, 12));
// Ajouter les 3 index séparés
model.addAttribute("pagePrivees", pagePrivees);
model.addAttribute("pagePubliques", pagePubliques);
model.addAttribute("pagePartagees", pagePartagees);
model.addAttribute("pageMesPartagees", pageMesPartagees);
return "mes-photos";
}
/* ========================== GALERIE ========================== */
@GetMapping("/galerie")
public String galerie(@RequestParam(defaultValue = "0") int page, Model model) {
Page<Photo> photosPage = photoService.listPublic(page, 12);
Page<PhotoDTO> photosPage = photoService.listPublic(page, 12);
model.addAttribute("photosPage", photosPage);
model.addAttribute("currentPage", page);
return "galerie";
}
/* ========================== DETAIL PHOTO ========================== */
@GetMapping("/photo/{id}")
@PreAuthorize("@securityService.canAccessPhoto(authentication, #id)")
public String viewPhoto(@PathVariable Long id,
@RequestParam(defaultValue = "0") int page,
Model model,
Authentication auth) {
Photo photo = photoRepository.findById(id).orElse(null);
if (photo == null) {
Authentication auth,
Model model) {
PhotoDTO photo = photoService.getPhotoById(id);
if (photo == null)
return "redirect:/galerie";
}
model.addAttribute("photo", photo);
// Pagination des commentaires
model.addAttribute("commentairesPage",
commentaireService.listByPhoto(id, page, 10));
Page<CommentaireDTO> commentaires =
commentaireService.listByPhoto(id, page, 10);
model.addAttribute("commentairesPage", commentaires);
model.addAttribute("currentPage", page);
// utilisateur connecté (peut être null)
String currentUser = (auth != null ? auth.getName() : null);
model.addAttribute("currentUser", currentUser);
// Liste des partages
List<Partage> partages = partageRepository.findByPhoto_Id(id);
model.addAttribute("partages", partages);
model.addAttribute("partages",
partageService.getPartagesForPhoto(id));
return "photo-detail";
}
/* ========================== COMMENTAIRES ========================== */
@PostMapping("/photo/{id}/comment")
public String addComment(@PathVariable Long id,
@RequestParam String contenu,
Authentication auth) {
if (auth == null) {
return "redirect:/login";
}
String email = auth.getName();
commentaireService.addComment(id, email, contenu);
commentaireService.addComment(id, auth.getName(), contenu);
return "redirect:/photo/" + id;
}
/* ========================== PARTAGE PHOTO ========================== */
@PostMapping("/photo/{id}/share")
@PreAuthorize("@securityService.canAccessPhoto(authentication, #id)")
public String share(@PathVariable Long id,
@RequestParam String email,
Authentication auth) {
// Vérifier que c'est le propriétaire
Photo photo = photoRepository.findById(id).orElse(null);
if (photo == null) return "redirect:/galerie";
if (!photo.getProprietaire().getEmail().equals(auth.getName())) {
return "redirect:/photo/" + id + "?error=notowner";
}
// Trouver utilisateur
Utilisateur user = utilisateurRepository.findByEmail(email).orElse(null);
if (user == null) {
return "redirect:/photo/" + id + "?error=usernotfound";
}
// Ajouter partage
Partage p = new Partage();
p.setPhoto(photo);
p.setUtilisateur(user);
partageRepository.save(p);
public String sharePhoto(@PathVariable Long id,
@RequestParam String email,
@RequestParam String permission,
Authentication auth) {
partageService.share(id, email, permission, auth.getName());
return "redirect:/photo/" + id + "?shared=ok";
}
@GetMapping("/photo/{id}/unshare/{email}")
public String unshare(@PathVariable Long id, @PathVariable String email) {
photoService.unshare(id, email);
partageService.unshare(id, email);
return "redirect:/photo/" + id;
}
}
}