Skip to content

[ALS-10196] [ALS-10195] Add configuration endpoint and table#245

Merged
srpiatt merged 14 commits into
mainfrom
feature/configuration2
Jun 8, 2026
Merged

[ALS-10196] [ALS-10195] Add configuration endpoint and table#245
srpiatt merged 14 commits into
mainfrom
feature/configuration2

Conversation

@srpiatt

@srpiatt srpiatt commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Configuration management API: list/get endpoints plus admin-only create/update/delete with persistent storage and DB migration.
  • Documentation

    • Fixed README typo and improved command/code block formatting.
  • Tests

    • Added/expanded tests for configuration endpoints, service behavior, and auth-filter exclusion rules.
  • Chores

    • Authentication filter allowlists public paths, preserves unauthenticated system-status behavior, and improves auth/role logging; security context now logs role-check diagnostics.

@srpiatt srpiatt self-assigned this May 27, 2026
@srpiatt srpiatt added the enhancement New feature or request label May 27, 2026
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Gcolon021, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 53 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0b3d269-4873-4dee-98af-02a952ea8d55

📥 Commits

Reviewing files that changed from the base of the PR and between a5f7573 and 105e9ba.

📒 Files selected for processing (4)
  • pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/AuthUser.java
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/AuthSecurityContext.java
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java
  • pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/ConfigurationRSTest.java
📝 Walkthrough

Walkthrough

Adds a configuration management feature: DB migration, JPA entity and DTO, repository and BaseRepository updates, ConfigurationService CRUD, REST endpoints with SUPER_ADMIN-protected writes, JWTFilter allowlist for public reads, persistence registration, and unit tests.

Changes

Configuration Management Feature

Layer / File(s) Summary
Configuration entity and request DTO
pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/Configuration.java, pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/request/ConfigurationRequest.java
Configuration JPA entity with name, kind, value (TEXT), description, markForDelete, fluent accessors, patch() and fromRequest(). ConfigurationRequest DTO with @Pattern/@Size validation and OpenAPI schema.
Database migration and schema
pic-sure-api-data/src/main/resources/db/sql/V8__ADD_CONFIG_TABLE.sql
Adds configuration table in picsure schema with UUID PK, composite unique constraint on (name,kind), value column as TEXT, optional description, and markForDelete flag.
Repository layer and data access
pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/repository/BaseRepository.java, pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/repository/ConfigurationRepository.java, pic-sure-api-war/src/main/resources/META-INF/persistence.xml
Adds ConfigurationRepository extending BaseRepository<Configuration,UUID>. BaseRepository reformatted and updated to build typed Predicate[] arrays from Maps. Registers Configuration in persistence.xml.
Configuration service with CRUD logic
pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/service/ConfigurationService.java
Implements transactional CRUD: getConfigurations(kind), getConfigurationByIdentifier(identifier) (UUID first, then name), addConfiguration(request) and updateConfiguration(request) with (name,kind) uniqueness checks, and deleteConfiguration(id).
REST API endpoints for configurations
pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/ConfigurationRS.java
JAX-RS resource at /configuration: @PermitAll GET list and single-item endpoints; @RolesAllowed("SUPER_ADMIN") POST/PATCH/DELETE for create/update/delete. PATCH enforces UUID immutability.
JWT filter path allowlist for configuration endpoints
pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java
Adds PathRule helper and EXCLUDED_PATHS allowlist (including GET /openapi.json, GET /configuration variants, proxy logging path). Annotates filter with @Priority(Priorities.AUTHENTICATION) and early-returns for allowed paths; preserves special-case /system/status behavior and logs introspection info.
Service layer unit tests
pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/service/ConfigurationServiceTest.java
Mockito-based tests covering list, identifier lookup (UUID/name), add with conflict handling, update with field patching and conflict detection, and delete with error paths.
REST endpoint and security filter tests
pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/ConfigurationRSTest.java, pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/security/JWTFilterTest.java
Reflection tests asserting @RolesAllowed(SUPER_ADMIN) on mutating endpoints and @PermitAll on reads; JWTFilter tests for excluded-path allowlist and denial cases.
AuthSecurityContext logging
pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/AuthSecurityContext.java
Adds SLF4J logger and logs diagnostic info in isUserInRole() while keeping role-check semantics.
README documentation updates
README.md
Fixes typo "Pre-requisits" → "Pre-requisites" and wraps build/run commands and JVM args in fenced code blocks.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ConfigurationRS
  participant ConfigurationService
  participant ConfigurationRepository
  participant Database
  Client->>ConfigurationRS: HTTP request (GET/POST/PATCH/DELETE)
  ConfigurationRS->>ConfigurationService: delegate operation
  ConfigurationService->>ConfigurationRepository: query/persist/merge/remove
  ConfigurationRepository->>Database: SQL SELECT/INSERT/UPDATE/DELETE
  ConfigurationService-->>ConfigurationRS: Optional result
  ConfigurationRS-->>Client: JSON response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A rabbit hops through configs new,
Keys and kinds in tidy rows,
SUPER_ADMIN guards the gate,
Services hum and tests propose,
DB and docs aligned in prose. 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective of the changeset: adding a configuration endpoint and corresponding database table, which aligns with the primary deliverables across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/configuration2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@srpiatt srpiatt force-pushed the feature/configuration2 branch from b2f663e to 9ae4483 Compare May 29, 2026 19:11
@srpiatt srpiatt marked this pull request as ready for review May 29, 2026 19:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/Configuration.java`:
- Around line 83-87: The Configuration.toString() currently includes the raw
'value' field which may leak secrets; update the Configuration.toString() method
to stop serializing the raw value (field 'value')—either omit it, replace it
with a fixed placeholder like "[REDACTED]" or a boolean flag (e.g., "hasValue":
value != null), and keep other fields the same; modify the
Json.createObjectBuilder() call in the Configuration.toString() implementation
to use the masked/omitted representation for the 'value' field instead of
value.toString().

In
`@pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/request/ConfigurationRequest.java`:
- Around line 20-23: The name and kind fields in ConfigurationRequest
(ConfigurationRequest.name and ConfigurationRequest.kind) — and the other
Pattern-annotated string field in the same class — lack a max-length constraint
and can exceed the DB column; add a `@Size`(max = 255) annotation to each of these
String fields (and import javax.validation.constraints.Size) so API validation
enforces the 255-character DB limit before persistence.

In
`@pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java`:
- Around line 135-143: Normalize the request path from
requestContext.getUriInfo().getPath() before using EXCLUDED_PATHS or comparing
to "/system/status": compute a normalizedPath variable (e.g., ensure it starts
with a leading '/' by prefixing one when missing) and use normalizedPath in the
EXCLUDED_PATHS.stream().anyMatch(...) check and in the path/contentEquals check
(replace path.contentEquals("/system/status") with
normalizedPath.contentEquals("/system/status")), keeping the existing
HttpMethod.GET comparison; update JWTFilter to use normalizedPath everywhere
downstream.

In
`@pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/service/ConfigurationService.java`:
- Around line 43-52: getConfigurationByIdentifier currently parses the
identifier as a UUID and returns early if getById(uuid) yields no result, which
prevents falling back to name when the identifier is UUID-shaped; modify
getConfigurationByIdentifier to (1) still attempt UUID.fromString(identifier)
and call configurationRepository.getById(uuid) via the existing method, (2) if
getById returns null/empty, then perform the name lookup using
configurationRepository.getByColumn("name", identifier) and return the first
match if present, and (3) retain the existing catch for IllegalArgumentException
to handle non-UUID identifiers and perform the same name lookup there; reference
the method getConfigurationByIdentifier and the repository calls
configurationRepository.getById and configurationRepository.getByColumn.
- Around line 81-90: The code currently calls config.patch(request) on the
managed Configuration before checking for (name, kind) collisions; instead,
create a candidate representation (e.g., compute the would-be name and kind or
clone the config into a transient DTO/object) using request values and run
nameKindPairExists against that candidate, and only call config.patch(request)
on the managed entity if the uniqueness check passes; refer to
ConfigurationService methods using configurationRepository.getById(...),
nameKindPairExists(...), and config.patch(...) to locate where to build/validate
the candidate and defer patching the managed entity until after the check.

In
`@pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/ConfigurationRSTest.java`:
- Around line 38-50: The test currently only ensures methods are not restricted
to SUPER_ADMIN; change it to assert public-read explicitly by requiring
`@PermitAll` on the endpoint method (or at the class level). Update
assertNotRestrictedToSuperAdmin to check method.getAnnotation(PermitAll.class)
!= null or if absent, check ConfigurationRS.class.getAnnotation(PermitAll.class)
!= null, and fail if neither is present or if any RolesAllowed exists (e.g.,
ensure rolesAllowed == null). Apply this check for
ConfigurationRS.getConfigurations and ConfigurationRS.getConfigurationById.

In
`@pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/security/JWTFilterTest.java`:
- Around line 133-140: The testExcludedFilterPaths_openapi in JWTFilterTest
currently only verifies setProperty("username") was not called which can miss
cases where the filter aborted the request; update the test to also assert the
request was not aborted and no auth-header was read by verifying
filter.filter(ctx) did not call ctx.abortWith(any(Response.class)) and did not
call ctx.getHeaderString("Authorization") (use verify(ctx, never()) with
appropriate matchers) after invoking filter.filter(ctx) to prevent false
positives.

In
`@pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/service/ConfigurationServiceTest.java`:
- Around line 277-297: The test updateConfiguration_changeName_nameKindCollision
is not actually exercising a (name, kind) collision because
request.setKind("some other kind") differs from the duplicate config2.kind;
change the request to use the same kind as the duplicate (request.setKind("some
kind")) so the (name, kind) pair collides, and tighten the stub for
configurationRepository.getByColumns to match the requested name and kind (e.g.
use argument matchers for the request name/kind instead of broad any()) to
ensure the duplicateNames return is triggered when
configurationService.updateConfiguration(request) runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 27aaf838-c2bf-4504-8e25-44366a3349d6

📥 Commits

Reviewing files that changed from the base of the PR and between fee4ba8 and 9ae4483.

📒 Files selected for processing (13)
  • README.md
  • pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/entity/Configuration.java
  • pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/repository/BaseRepository.java
  • pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/repository/ConfigurationRepository.java
  • pic-sure-api-data/src/main/java/edu/harvard/dbmi/avillach/data/request/ConfigurationRequest.java
  • pic-sure-api-data/src/main/resources/db/sql/V8__ADD_CONFIG_TABLE.sql
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/ConfigurationRS.java
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/service/ConfigurationService.java
  • pic-sure-api-war/src/main/resources/META-INF/persistence.xml
  • pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/ConfigurationRSTest.java
  • pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/security/JWTFilterTest.java
  • pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/service/ConfigurationServiceTest.java

Comment thread pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java Outdated
Comment thread pic-sure-api-war/src/test/java/edu/harvard/dbmi/avillach/ConfigurationRSTest.java Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/AuthSecurityContext.java`:
- Line 38: The log in AuthSecurityContext.isUserInRole currently uses
logger.info and should be reduced to diagnostic level and/or gated: change the
call from logger.info(...) to logger.debug(...) or logger.trace(...), and wrap
the logging with a logger.isDebugEnabled() (or isTraceEnabled()) check; also
consider removing sensitive details (user.getRoles() and explicit result) or
only include them behind a development-only flag so production logs do not emit
authorization decisions.
- Around line 36-37: Add a TODO marker and ticket reference to the temporary
diagnostic comment in AuthSecurityContext to ensure it’s tracked for removal;
locate the diagnostic comment in the AuthSecurityContext class (the block
beginning "// TEMP DIAGNOSTIC...") and update it to include a TODO with a ticket
id (e.g., TODO ALS-10196 or create a new issue number) and brief intent/expiry
so reviewers can find and remove the diagnostic after root-causing `@RolesAllowed`
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3ba392b4-1611-406f-b6a0-f9b53452ef6d

📥 Commits

Reviewing files that changed from the base of the PR and between f9e2927 and 592a8de.

📒 Files selected for processing (2)
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/AuthSecurityContext.java
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/security/JWTFilter.java

@srpiatt srpiatt marked this pull request as draft June 1, 2026 16:34
@srpiatt srpiatt marked this pull request as ready for review June 2, 2026 17:33
Comment thread pic-sure-api-war/src/main/java/edu/harvard/dbmi/avillach/ConfigurationRS.java Outdated
Gcolon021 added 2 commits June 4, 2026 14:49
Role checks now match against the user's privileges (AuthSecurityContext),
so ConfigurationRS @RolesAllowed annotations name the SUPER_ADMIN privilege
rather than the 'PIC-SURE Top Admin' role. Update the guard test to assert
SUPER_ADMIN, matching the current annotations.
@srpiatt srpiatt merged commit ef33e29 into main Jun 8, 2026
4 checks passed
@srpiatt srpiatt deleted the feature/configuration2 branch June 8, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants