Skip to content

Commit 69ad61b

Browse files
committed
fix(gdpr): address PR review feedback for validation and documentation
Address code review feedback from PR #252: - ConsentRequestDto: Change regex pattern from * to + to prevent empty strings from passing validation for custom consent types - GdprDeletionService: Capture user email at start of executeUserDeletion() before entity deletion to avoid potential entity lifecycle issues when publishing UserDeletedEvent - FileAuditLogQueryService: Enhance JavaDoc with detailed performance warning about file-scanning limitations (<50MB, <100K events) and recommendations for high-volume production deployments
1 parent ba40f71 commit 69ad61b

3 files changed

Lines changed: 16 additions & 4 deletions

File tree

src/main/java/com/digitalsanctuary/spring/user/audit/FileAuditLogQueryService.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,19 @@
2626
*
2727
* <p>This implementation reads and parses the entire log file for each query,
2828
* filtering results by user email or ID. While suitable for small to medium
29-
* audit volumes, applications with high audit volumes should consider implementing
30-
* a database-backed query service.
29+
* audit volumes (&lt;50MB, &lt;100K events), applications with high audit volumes
30+
* or frequent export requests should consider implementing a database-backed
31+
* query service for better performance.
32+
*
33+
* <p><strong>Performance Note:</strong> GDPR export operations call this service
34+
* multiple times (findByUser, findByUserAndAction) which results in reading
35+
* and parsing the entire log file for each call. For production deployments
36+
* with large audit logs, consider:
37+
* <ul>
38+
* <li>Implementing a database-backed {@link AuditLogQueryService}</li>
39+
* <li>Adding log rotation to keep file sizes manageable</li>
40+
* <li>Using indexed storage for audit events</li>
41+
* </ul>
3142
*
3243
* <p>The log file format is:
3344
* {@code Date|Action|ActionStatus|UserId|Email|IPAddress|SessionId|Message|UserAgent|ExtraData}

src/main/java/com/digitalsanctuary/spring/user/dto/ConsentRequestDto.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class ConsentRequestDto {
3333
* Must contain only alphanumeric characters, underscores, and hyphens.
3434
*/
3535
@Size(max = 100, message = "Custom type must not exceed 100 characters")
36-
@Pattern(regexp = "^[a-zA-Z0-9_-]*$", message = "Custom type can only contain letters, numbers, underscores, and hyphens")
36+
@Pattern(regexp = "^[a-zA-Z0-9_-]+$", message = "Custom type can only contain letters, numbers, underscores, and hyphens")
3737
private String customType;
3838

3939
/**

src/main/java/com/digitalsanctuary/spring/user/gdpr/GdprDeletionService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public DeletionResult deleteUser(User user, boolean exportBeforeDeletion) {
150150
@Transactional
151151
protected DeletionResult executeUserDeletion(User user, GdprExportDTO exportedData, boolean wasExported) {
152152
Long userId = user.getId();
153+
String userEmail = user.getEmail();
153154

154155
// Step 2: Notify all GdprDataContributors to prepare for deletion
155156
prepareContributorsForDeletion(user);
@@ -168,7 +169,7 @@ protected DeletionResult executeUserDeletion(User user, GdprExportDTO exportedDa
168169
log.info("GdprDeletionService.deleteUser: Successfully deleted user {}", userId);
169170

170171
// Step 6: Publish UserDeletedEvent after successful deletion
171-
eventPublisher.publishEvent(new UserDeletedEvent(this, userId, user.getEmail(), wasExported));
172+
eventPublisher.publishEvent(new UserDeletedEvent(this, userId, userEmail, wasExported));
172173

173174
return wasExported
174175
? DeletionResult.successWithExport(exportedData)

0 commit comments

Comments
 (0)