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.multipart.MultipartFile;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Controller
|
||||
public class PhotoController {
|
||||
|
||||
@@ -181,8 +184,13 @@ public class PhotoController {
|
||||
@RequestParam String permission,
|
||||
Authentication auth) {
|
||||
|
||||
partageService.share(id, email, permission, auth.getName());
|
||||
return "redirect:/photo/" + id + "?shared=ok";
|
||||
try {
|
||||
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);
|
||||
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;
|
||||
|
||||
public class PartageMapper {
|
||||
|
||||
public static PartageDTO toDTO(Partage p) {
|
||||
if (p == null) return null;
|
||||
|
||||
PartageDTO dto = new PartageDTO();
|
||||
dto.setId(p.getId());
|
||||
dto.setPermission(p.getPermission().name());
|
||||
dto.setUtilisateur(UtilisateurMapper.toDTO(p.getUtilisateur()));
|
||||
dto.setPhoto(PhotoMapper.toDTO(p.getPhoto()));
|
||||
dto.setPermission(p.getPermission().name());
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,5 +13,5 @@ public interface PartageService {
|
||||
boolean canView(Long photoId, String email);
|
||||
boolean canComment(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
|
||||
public void share(Long photoId, String targetEmail, String permissionStr, String ownerEmail) {
|
||||
|
||||
Photo photo = photoRepository.findById(photoId)
|
||||
.orElseThrow(() -> new RuntimeException("Photo introuvable"));
|
||||
|
||||
if (!photo.getProprietaire().getEmail().equals(ownerEmail))
|
||||
throw new RuntimeException("Vous n'êtes pas propriétaire");
|
||||
|
||||
Utilisateur target = utilisateurRepository.findByEmail(targetEmail)
|
||||
.orElseThrow(() -> new RuntimeException("Utilisateur introuvable"));
|
||||
|
||||
if (partageRepository.existsByPhoto_IdAndUtilisateur_Email(photoId, targetEmail))
|
||||
return;
|
||||
|
||||
// Nouveauté ici : renvoyer un message explicite
|
||||
if (partageRepository.existsByPhoto_IdAndUtilisateur_Email(photoId, targetEmail)) {
|
||||
throw new RuntimeException("Cet utilisateur a déjà accès à cette photo");
|
||||
}
|
||||
Partage.Permission permission = Partage.Permission.valueOf(permissionStr);
|
||||
|
||||
Partage partage = new Partage();
|
||||
partage.setPhoto(photo);
|
||||
partage.setUtilisateur(target);
|
||||
partage.setPermission(permission);
|
||||
|
||||
partageRepository.save(partage);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void unshare(Long photoId, String targetEmail) {
|
||||
|
||||
@@ -121,4 +117,28 @@ public class PartageServiceImpl implements PartageService {
|
||||
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>
|
||||
|
||||
<!-- Partage de la photo -->
|
||||
<h2>Partagée avec :</h2>
|
||||
<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 -->
|
||||
<!-- Formulaire gestion visible uniquement en ADMIN ou PROPRIÉTAIRE -->
|
||||
<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>
|
||||
<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">
|
||||
<label>Email de l'utilisateur :</label>
|
||||
<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>
|
||||
|
||||
<!-- Partage de la photo -->
|
||||
<h2>Partagée avec :</h2>
|
||||
<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 -->
|
||||
<!-- Formulaire gestion visible uniquement en ADMIN ou PROPRIÉTAIRE -->
|
||||
<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>
|
||||
<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">
|
||||
<label>Email de l'utilisateur :</label>
|
||||
<input type="email" name="email" required />
|
||||
|
||||
Reference in New Issue
Block a user