fix(review): replace Set<Person> with Set<PersonView> in GeschichteView — prevents leaking admin fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,10 +81,14 @@ public class GeschichteService {
|
||||
if (displayName.isBlank()) displayName = "[Unbekannt]";
|
||||
authorView = new GeschichteView.AuthorView(author.getId(), displayName);
|
||||
}
|
||||
Set<GeschichteView.PersonView> personViews = new HashSet<>();
|
||||
for (Person p : g.getPersons()) {
|
||||
personViews.add(new GeschichteView.PersonView(p.getId(), p.getFirstName(), p.getLastName()));
|
||||
}
|
||||
return new GeschichteView(
|
||||
g.getId(), g.getTitle(), g.getBody(),
|
||||
g.getStatus(), g.getType(),
|
||||
authorView, g.getPersons(),
|
||||
authorView, personViews,
|
||||
items,
|
||||
g.getPublishedAt(), g.getCreatedAt(), g.getUpdatedAt()
|
||||
);
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.raddatz.familienarchiv.geschichte;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.raddatz.familienarchiv.geschichte.journeyitem.JourneyItemView;
|
||||
import org.raddatz.familienarchiv.person.Person;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
@@ -21,7 +20,7 @@ public record GeschichteView(
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) GeschichteStatus status,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) GeschichteType type,
|
||||
AuthorView author,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) Set<Person> persons,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) Set<PersonView> persons,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) List<JourneyItemView> items,
|
||||
LocalDateTime publishedAt,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) LocalDateTime createdAt,
|
||||
@@ -32,4 +31,11 @@ public record GeschichteView(
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID id,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String displayName
|
||||
) {}
|
||||
|
||||
/** Summarised person — exposes only id, firstName, and lastName. No admin-only fields. */
|
||||
public record PersonView(
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID id,
|
||||
String firstName,
|
||||
String lastName
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ class GeschichteServiceIntegrationTest {
|
||||
assertThat(geschichteService.list(null, List.of(franz.getId()), 50)).hasSize(1);
|
||||
GeschichteView fetched = geschichteService.getById(draftId);
|
||||
assertThat(fetched.title()).isEqualTo("Erinnerung an Opa Franz");
|
||||
assertThat(fetched.persons()).extracting(Person::getId).containsExactly(franz.getId());
|
||||
assertThat(fetched.persons()).extracting(GeschichteView.PersonView::id).containsExactly(franz.getId());
|
||||
|
||||
// Delete as writer; join rows go with it
|
||||
authenticateAs(writer, Permission.BLOG_WRITE);
|
||||
|
||||
@@ -153,6 +153,26 @@ class GeschichteServiceTest {
|
||||
assertThat(result.author().displayName()).doesNotContain("secret@test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getById_persons_are_mapped_to_PersonView() {
|
||||
authenticateAs(reader, Permission.READ_ALL);
|
||||
UUID id = UUID.randomUUID();
|
||||
UUID personId = UUID.randomUUID();
|
||||
Geschichte published = published(id);
|
||||
published.setPersons(new HashSet<>(List.of(
|
||||
Person.builder().id(personId).firstName("Franz").lastName("Raddatz").build()
|
||||
)));
|
||||
when(geschichteRepository.findById(id)).thenReturn(Optional.of(published));
|
||||
|
||||
GeschichteView result = geschichteService.getById(id);
|
||||
|
||||
assertThat(result.persons()).hasSize(1);
|
||||
GeschichteView.PersonView pv = result.persons().iterator().next();
|
||||
assertThat(pv.id()).isEqualTo(personId);
|
||||
assertThat(pv.firstName()).isEqualTo("Franz");
|
||||
assertThat(pv.lastName()).isEqualTo("Raddatz");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getById_items_come_from_journeyItemService() {
|
||||
authenticateAs(reader, Permission.READ_ALL);
|
||||
|
||||
Reference in New Issue
Block a user