Weiter an den Locations gearbeitet
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled

This commit is contained in:
2026-04-06 22:48:34 +02:00
parent 0f9f109067
commit 5ffb99c9b5
81 changed files with 2817 additions and 352 deletions

View File

@@ -0,0 +1,176 @@
package de.oaa.xxx.location;
import de.oaa.xxx.location.entity.LocationAdminEntity;
import de.oaa.xxx.location.repository.LocationAdminRepository;
import de.oaa.xxx.location.repository.LocationRepository;
import de.oaa.xxx.user.UserRepository;
import de.oaa.xxx.user.UserService;
import jakarta.transaction.Transactional;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/locations/{locationId}/admins")
public class LocationAdminController {
record AdminDto(UUID userId, String name, String profilePicture, boolean isOwner) {}
record AddAdminRequest(UUID userId) {}
record TransferOwnerRequest(UUID userId) {}
private final LocationRepository locationRepo;
private final LocationAdminRepository adminRepo;
private final UserRepository userRepo;
private final UserService userService;
public LocationAdminController(LocationRepository locationRepo,
LocationAdminRepository adminRepo,
UserRepository userRepo,
UserService userService) {
this.locationRepo = locationRepo;
this.adminRepo = adminRepo;
this.userRepo = userRepo;
this.userService = userService;
}
// ── Hilfsmethoden ────────────────────────────────────────────────────────
private boolean isAdmin(UUID locationId, UUID userId, de.oaa.xxx.location.entity.LocationEntity loc) {
return loc.getOwnerId().equals(userId)
|| adminRepo.existsByLocationIdAndUserId(locationId, userId);
}
private AdminDto toDto(UUID userId, de.oaa.xxx.location.entity.LocationEntity loc) {
return userRepo.findById(userId).map(u -> new AdminDto(
u.getUserId(), u.getName(), u.getProfilePicture(),
u.getUserId().equals(loc.getOwnerId())))
.orElse(null);
}
// ── Admins auflisten ─────────────────────────────────────────────────────
@GetMapping
public ResponseEntity<List<AdminDto>> list(
@PathVariable UUID locationId,
Principal principal) {
userService.requireUser(principal);
var locOpt = locationRepo.findById(locationId);
if (locOpt.isEmpty()) return ResponseEntity.notFound().build();
var loc = locOpt.get();
// Inhaber ist immer erster Eintrag
List<AdminDto> admins = new java.util.ArrayList<>();
userRepo.findById(loc.getOwnerId()).ifPresent(owner ->
admins.add(new AdminDto(owner.getUserId(), owner.getName(), owner.getProfilePicture(), true)));
adminRepo.findByLocationId(locationId).stream()
.filter(a -> !a.getUserId().equals(loc.getOwnerId())) // Inhaber nicht doppelt
.map(a -> toDto(a.getUserId(), loc))
.filter(java.util.Objects::nonNull)
.forEach(admins::add);
return ResponseEntity.ok(admins);
}
// ── Admin hinzufügen ──────────────────────────────────────────────────────
@PostMapping
public ResponseEntity<AdminDto> add(
@PathVariable UUID locationId,
@RequestBody AddAdminRequest req,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var locOpt = locationRepo.findById(locationId);
if (locOpt.isEmpty()) return ResponseEntity.notFound().build();
var loc = locOpt.get();
if (!isAdmin(locationId, myId, loc)) return ResponseEntity.status(403).build();
if (req.userId() == null || !userRepo.existsById(req.userId()))
return ResponseEntity.badRequest().build();
// Inhaber muss nicht eingetragen werden
if (req.userId().equals(loc.getOwnerId()))
return ResponseEntity.badRequest().build();
// Bereits Admin?
if (adminRepo.existsByLocationIdAndUserId(locationId, req.userId()))
return ResponseEntity.status(409).build();
LocationAdminEntity entity = new LocationAdminEntity();
entity.setAdminId(UUID.randomUUID());
entity.setLocationId(locationId);
entity.setUserId(req.userId());
entity.setAddedAt(LocalDateTime.now());
adminRepo.save(entity);
return ResponseEntity.status(201).body(toDto(req.userId(), loc));
}
// ── Admin entfernen ───────────────────────────────────────────────────────
@Transactional
@DeleteMapping("/{userId}")
public ResponseEntity<Void> remove(
@PathVariable UUID locationId,
@PathVariable UUID userId,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var locOpt = locationRepo.findById(locationId);
if (locOpt.isEmpty()) return ResponseEntity.notFound().build();
var loc = locOpt.get();
if (!isAdmin(locationId, myId, loc)) return ResponseEntity.status(403).build();
// Inhaber darf nicht entfernt werden
if (userId.equals(loc.getOwnerId())) return ResponseEntity.status(403).build();
adminRepo.deleteByLocationIdAndUserId(locationId, userId);
return ResponseEntity.noContent().build();
}
// ── Inhaberwechsel ────────────────────────────────────────────────────────
@Transactional
@PutMapping("/transfer-owner")
public ResponseEntity<Map<String, Object>> transferOwner(
@PathVariable UUID locationId,
@RequestBody TransferOwnerRequest req,
Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
var locOpt = locationRepo.findById(locationId);
if (locOpt.isEmpty()) return ResponseEntity.notFound().build();
var loc = locOpt.get();
// Nur der aktuelle Inhaber darf übertragen
if (!loc.getOwnerId().equals(myId)) return ResponseEntity.status(403).build();
if (req.userId() == null || !userRepo.existsById(req.userId()))
return ResponseEntity.badRequest().build();
if (req.userId().equals(myId)) return ResponseEntity.badRequest().build();
// Neuer Inhaber als Admin eintragen (falls noch nicht), alter Inhaber wird normaler Admin
if (!adminRepo.existsByLocationIdAndUserId(locationId, myId)) {
LocationAdminEntity a = new LocationAdminEntity();
a.setAdminId(UUID.randomUUID());
a.setLocationId(locationId);
a.setUserId(myId);
a.setAddedAt(LocalDateTime.now());
adminRepo.save(a);
}
// Neuen Inhaber aus Admin-Liste entfernen (er ist jetzt Owner)
adminRepo.deleteByLocationIdAndUserId(locationId, req.userId());
loc.setOwnerId(req.userId());
locationRepo.save(loc);
return ResponseEntity.ok(Map.of("newOwnerId", req.userId()));
}
}