CORRECTION BUG & AMELIORATION : Gestion de la visibilite et des partages de photos (ACL)
This commit is contained in:
@@ -18,6 +18,9 @@ import org.springframework.ui.Model;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class PhotoController {
|
public class PhotoController {
|
||||||
|
|
||||||
@@ -181,8 +184,13 @@ public class PhotoController {
|
|||||||
@RequestParam String permission,
|
@RequestParam String permission,
|
||||||
Authentication auth) {
|
Authentication auth) {
|
||||||
|
|
||||||
partageService.share(id, email, permission, auth.getName());
|
try {
|
||||||
return "redirect:/photo/" + id + "?shared=ok";
|
partageService.share(id, email, permission, auth.getName());
|
||||||
|
return "redirect:/photo/" + id + "?shared=ok";
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
return "redirect:/photo/" + id + "?error=" + URLEncoder.encode(ex.getMessage(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,4 +201,18 @@ public class PhotoController {
|
|||||||
partageService.unshare(id, email);
|
partageService.unshare(id, email);
|
||||||
return "redirect:/photo/" + id;
|
return "redirect:/photo/" + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== MAJ MODE PARTAGE ========================== */
|
||||||
|
@PostMapping("/photo/{id}/share/update")
|
||||||
|
@PreAuthorize("@securityService.canAccessPhoto(authentication, #id)")
|
||||||
|
public String updateShare(
|
||||||
|
@PathVariable Long id,
|
||||||
|
@RequestParam String email,
|
||||||
|
@RequestParam String permission,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
partageService.updatePermission(id, email, permission, auth.getName());
|
||||||
|
return "redirect:/photo/" + id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,17 +4,17 @@ import local.epul4a.fotosharing.dto.PartageDTO;
|
|||||||
import local.epul4a.fotosharing.model.Partage;
|
import local.epul4a.fotosharing.model.Partage;
|
||||||
|
|
||||||
public class PartageMapper {
|
public class PartageMapper {
|
||||||
|
|
||||||
public static PartageDTO toDTO(Partage p) {
|
public static PartageDTO toDTO(Partage p) {
|
||||||
if (p == null) return null;
|
if (p == null) return null;
|
||||||
|
|
||||||
PartageDTO dto = new PartageDTO();
|
PartageDTO dto = new PartageDTO();
|
||||||
dto.setId(p.getId());
|
dto.setId(p.getId());
|
||||||
|
dto.setPermission(p.getPermission().name());
|
||||||
dto.setUtilisateur(UtilisateurMapper.toDTO(p.getUtilisateur()));
|
dto.setUtilisateur(UtilisateurMapper.toDTO(p.getUtilisateur()));
|
||||||
dto.setPhoto(PhotoMapper.toDTO(p.getPhoto()));
|
dto.setPhoto(PhotoMapper.toDTO(p.getPhoto()));
|
||||||
dto.setPermission(p.getPermission().name());
|
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ public interface PartageService {
|
|||||||
boolean canView(Long photoId, String email);
|
boolean canView(Long photoId, String email);
|
||||||
boolean canComment(Long photoId, String email);
|
boolean canComment(Long photoId, String email);
|
||||||
boolean canAdmin(Long photoId, String email);
|
boolean canAdmin(Long photoId, String email);
|
||||||
|
void updatePermission(Long photoId, String targetEmail, String newPermission, String ownerEmail);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,29 +40,25 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void share(Long photoId, String targetEmail, String permissionStr, String ownerEmail) {
|
public void share(Long photoId, String targetEmail, String permissionStr, String ownerEmail) {
|
||||||
|
|
||||||
Photo photo = photoRepository.findById(photoId)
|
Photo photo = photoRepository.findById(photoId)
|
||||||
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
||||||
|
|
||||||
if (!photo.getProprietaire().getEmail().equals(ownerEmail))
|
if (!photo.getProprietaire().getEmail().equals(ownerEmail))
|
||||||
throw new RuntimeException("Vous n'êtes pas propriétaire");
|
throw new RuntimeException("Vous n'êtes pas propriétaire");
|
||||||
|
|
||||||
Utilisateur target = utilisateurRepository.findByEmail(targetEmail)
|
Utilisateur target = utilisateurRepository.findByEmail(targetEmail)
|
||||||
.orElseThrow(() -> new RuntimeException("Utilisateur introuvable"));
|
.orElseThrow(() -> new RuntimeException("Utilisateur introuvable"));
|
||||||
|
// Nouveauté ici : renvoyer un message explicite
|
||||||
if (partageRepository.existsByPhoto_IdAndUtilisateur_Email(photoId, targetEmail))
|
if (partageRepository.existsByPhoto_IdAndUtilisateur_Email(photoId, targetEmail)) {
|
||||||
return;
|
throw new RuntimeException("Cet utilisateur a déjà accès à cette photo");
|
||||||
|
}
|
||||||
Partage.Permission permission = Partage.Permission.valueOf(permissionStr);
|
Partage.Permission permission = Partage.Permission.valueOf(permissionStr);
|
||||||
|
|
||||||
Partage partage = new Partage();
|
Partage partage = new Partage();
|
||||||
partage.setPhoto(photo);
|
partage.setPhoto(photo);
|
||||||
partage.setUtilisateur(target);
|
partage.setUtilisateur(target);
|
||||||
partage.setPermission(permission);
|
partage.setPermission(permission);
|
||||||
|
|
||||||
partageRepository.save(partage);
|
partageRepository.save(partage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unshare(Long photoId, String targetEmail) {
|
public void unshare(Long photoId, String targetEmail) {
|
||||||
|
|
||||||
@@ -121,4 +117,28 @@ public class PartageServiceImpl implements PartageService {
|
|||||||
return partage.getPermission() == Partage.Permission.ADMIN;
|
return partage.getPermission() == Partage.Permission.ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePermission(Long photoId, String targetEmail, String newPermission, String requesterEmail) {
|
||||||
|
Photo photo = photoRepository.findById(photoId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
||||||
|
//Vérifier si requester = propriétaire
|
||||||
|
if (!photo.getProprietaire().getEmail().equals(requesterEmail)) {
|
||||||
|
// Sinon, vérifier s'il a ADMIN
|
||||||
|
Partage requesterPartage = partageRepository
|
||||||
|
.findByPhoto_IdAndUtilisateur_Email(photoId, requesterEmail)
|
||||||
|
.orElse(null);
|
||||||
|
if (requesterPartage == null || requesterPartage.getPermission() != Partage.Permission.ADMIN) {
|
||||||
|
throw new RuntimeException("Vous n’avez pas les droits ADMIN pour modifier les permissions.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// OK → modification des droits
|
||||||
|
Partage partage = partageRepository
|
||||||
|
.findByPhoto_IdAndUtilisateur_Email(photoId, targetEmail)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Partage introuvable"));
|
||||||
|
Partage.Permission permission = Partage.Permission.valueOf(newPermission);
|
||||||
|
partage.setPermission(permission);
|
||||||
|
partageRepository.save(partage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,21 +31,34 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Partage de la photo -->
|
<!-- Partage de la photo -->
|
||||||
<h2>Partagée avec :</h2>
|
<!-- Formulaire gestion visible uniquement en ADMIN ou PROPRIÉTAIRE -->
|
||||||
<ul>
|
|
||||||
<li th:each="p : ${partages}">
|
|
||||||
<span th:text="${p.utilisateur.email}"></span>
|
|
||||||
<span> - <b th:text="${p.permission}"></b></span>
|
|
||||||
<!-- ADMIN OU PROPRIÉTAIRE : peut retirer -->
|
|
||||||
<a th:if="${canAdmin}"
|
|
||||||
th:href="@{'/photo/' + ${photo.id} + '/unshare/' + ${p.utilisateur.email}}"
|
|
||||||
style="color:red; margin-left:10px;">Retirer</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Formulaire d’ajout visible uniquement en ADMIN ou PROPRIÉTAIRE -->
|
|
||||||
<div th:if="${canAdmin}">
|
<div th:if="${canAdmin}">
|
||||||
|
<h2>Partagée avec :</h2>
|
||||||
|
<ul>
|
||||||
|
<li th:each="p : ${partages}">
|
||||||
|
<span th:text="${p.utilisateur.email}"></span>
|
||||||
|
<!-- Formulaire modification permission -->
|
||||||
|
<form th:action="@{'/photo/' + ${photo.id} + '/share/update'}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="email" th:value="${p.utilisateur.email}" />
|
||||||
|
<select name="permission">
|
||||||
|
<option value="READ" th:selected="${p.permission == 'READ'}">Lecture</option>
|
||||||
|
<option value="COMMENT" th:selected="${p.permission == 'COMMENT'}">Commentaire</option>
|
||||||
|
<option value="ADMIN" th:selected="${p.permission == 'ADMIN'}">Administration</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Modifier</button>
|
||||||
|
</form>
|
||||||
|
<!-- Unshare -->
|
||||||
|
<a th:href="@{'/photo/' + ${photo.id} + '/unshare/' + ${p.utilisateur.email}}"
|
||||||
|
style="color:red; margin-left:10px;">Retirer</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
<h3>Partager la photo</h3>
|
<h3>Partager la photo</h3>
|
||||||
|
<div th:if="${param.error}" style="color:red; font-weight:bold;">
|
||||||
|
<span th:text="${param.error}"></span>
|
||||||
|
</div>
|
||||||
|
<div th:if="${param.shared}" style="color:green; font-weight:bold;">
|
||||||
|
Partage effectué avec succès !
|
||||||
|
</div>
|
||||||
<form th:action="@{'/photo/' + ${photo.id} + '/share'}" method="post">
|
<form th:action="@{'/photo/' + ${photo.id} + '/share'}" method="post">
|
||||||
<label>Email de l'utilisateur :</label>
|
<label>Email de l'utilisateur :</label>
|
||||||
<input type="email" name="email" required />
|
<input type="email" name="email" required />
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -31,21 +31,34 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Partage de la photo -->
|
<!-- Partage de la photo -->
|
||||||
<h2>Partagée avec :</h2>
|
<!-- Formulaire gestion visible uniquement en ADMIN ou PROPRIÉTAIRE -->
|
||||||
<ul>
|
|
||||||
<li th:each="p : ${partages}">
|
|
||||||
<span th:text="${p.utilisateur.email}"></span>
|
|
||||||
<span> - <b th:text="${p.permission}"></b></span>
|
|
||||||
<!-- ADMIN OU PROPRIÉTAIRE : peut retirer -->
|
|
||||||
<a th:if="${canAdmin}"
|
|
||||||
th:href="@{'/photo/' + ${photo.id} + '/unshare/' + ${p.utilisateur.email}}"
|
|
||||||
style="color:red; margin-left:10px;">Retirer</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Formulaire d’ajout visible uniquement en ADMIN ou PROPRIÉTAIRE -->
|
|
||||||
<div th:if="${canAdmin}">
|
<div th:if="${canAdmin}">
|
||||||
|
<h2>Partagée avec :</h2>
|
||||||
|
<ul>
|
||||||
|
<li th:each="p : ${partages}">
|
||||||
|
<span th:text="${p.utilisateur.email}"></span>
|
||||||
|
<!-- Formulaire modification permission -->
|
||||||
|
<form th:action="@{'/photo/' + ${photo.id} + '/share/update'}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="email" th:value="${p.utilisateur.email}" />
|
||||||
|
<select name="permission">
|
||||||
|
<option value="READ" th:selected="${p.permission == 'READ'}">Lecture</option>
|
||||||
|
<option value="COMMENT" th:selected="${p.permission == 'COMMENT'}">Commentaire</option>
|
||||||
|
<option value="ADMIN" th:selected="${p.permission == 'ADMIN'}">Administration</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Modifier</button>
|
||||||
|
</form>
|
||||||
|
<!-- Unshare -->
|
||||||
|
<a th:href="@{'/photo/' + ${photo.id} + '/unshare/' + ${p.utilisateur.email}}"
|
||||||
|
style="color:red; margin-left:10px;">Retirer</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
<h3>Partager la photo</h3>
|
<h3>Partager la photo</h3>
|
||||||
|
<div th:if="${param.error}" style="color:red; font-weight:bold;">
|
||||||
|
<span th:text="${param.error}"></span>
|
||||||
|
</div>
|
||||||
|
<div th:if="${param.shared}" style="color:green; font-weight:bold;">
|
||||||
|
Partage effectué avec succès !
|
||||||
|
</div>
|
||||||
<form th:action="@{'/photo/' + ${photo.id} + '/share'}" method="post">
|
<form th:action="@{'/photo/' + ${photo.id} + '/share'}" method="post">
|
||||||
<label>Email de l'utilisateur :</label>
|
<label>Email de l'utilisateur :</label>
|
||||||
<input type="email" name="email" required />
|
<input type="email" name="email" required />
|
||||||
|
|||||||
Reference in New Issue
Block a user