Skip to content

Fix: use LoggedInInfo session validation in Scratch2Action#2175

Draft
LiamStanziani wants to merge 2 commits intomaintenancefrom
claude/issue-1889-20260127-1722
Draft

Fix: use LoggedInInfo session validation in Scratch2Action#2175
LiamStanziani wants to merge 2 commits intomaintenancefrom
claude/issue-1889-20260127-1722

Conversation

@LiamStanziani
Copy link
Copy Markdown
Collaborator

@LiamStanziani LiamStanziani commented Jan 27, 2026

Description

This PR fixes #1889 by replacing raw session attribute access with the proper LoggedInInfo pattern for session management and validation in Scratch2Action.java.

Changes

  • Add LoggedInInfo import
  • Update execute() to use LoggedInInfo.getLoggedInInfoFromSession()
  • Update delete() with session validation and ownership verification
  • Update showVersion() with session validation and ownership verification
  • Add proper HTTP status codes (401/403) for authentication/authorization failures
  • Implement PHI-safe logging with OWASP encoding

Security Improvements

  • All methods now properly validate sessions before processing
  • Authorization checks prevent users from accessing/modifying other users' data
  • Eliminates potential NullPointerException from raw session access
  • Follows the standard LoggedInInfo pattern used throughout the codebase

Testing

Please test:

  • Normal scratch pad operations with valid session
  • Scratch pad operations with expired/invalid session
  • Attempts to access/modify another user's scratch pad

Fixes #1889

Generated with Claude Code

Summary by Sourcery

Strengthen Scratch2Action session handling and authorization by standardizing on LoggedInInfo-based validation for scratch pad operations.

Bug Fixes:

  • Replace direct session attribute access with LoggedInInfo-based retrieval to prevent NullPointerExceptions and inconsistent authentication behavior.
  • Enforce ownership checks before viewing or deleting scratch pads to prevent unauthorized access or modification.
  • Return appropriate HTTP 401/403 status codes when authentication or authorization fails in scratch pad endpoints.

Enhancements:

  • Add PHI-safe, OWASP-encoded logging for authentication and authorization failures in scratch pad actions.

Summary by cubic

Replaced raw session access in Scratch2Action with the LoggedInInfo pattern and enforced strict auth checks. Prevents unauthorized access and returns proper 401/403 responses. Fixes #1889.

  • Refactors

    • Use LoggedInInfo.getLoggedInInfoFromSession() in execute, delete, and showVersion.
    • Remove direct session reads to avoid NPEs and ensure consistent auth handling.
  • Bug Fixes

    • Validate session and providerNo; return 401 when missing or invalid.
    • Enforce ownership for view/delete; return 403 on mismatch.
    • Add PHI-safe logging with OWASP encoding.

Written for commit 5dc0a58. Summary will update on new commits.

Replace raw session attribute access with LoggedInInfo pattern for
proper session management and validation. Add authorization checks
to ensure users can only access their own scratch pad data.

Changes:
- Add LoggedInInfo import
- Update execute() to use LoggedInInfo.getLoggedInInfoFromSession()
- Update delete() with session validation and ownership verification
- Update showVersion() with session validation and ownership verification
- Return appropriate HTTP status codes (401/403) for auth failures
- Add PHI-safe logging with OWASP encoding

Fixes #1889

Co-authored-by: Liam Stanziani <LiamStanziani@users.noreply.github.com>
@LiamStanziani LiamStanziani self-assigned this Jan 27, 2026
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Jan 27, 2026

Reviewer's Guide

Refactors Scratch2Action to use the centralized LoggedInInfo session helper, adds authentication and authorization checks for scratch pad access/modification, returns appropriate HTTP status codes on failure, and hardens logging with OWASP encoding and safer error handling.

Sequence diagram for Scratch2Action showVersion with session validation and ownership check

sequenceDiagram
    actor User
    participant Scratch2Action
    participant LoggedInInfo
    participant ScratchPadDao
    participant HttpServletResponse
    participant Logger

    User->>Scratch2Action: showVersion(request)
    Scratch2Action->>LoggedInInfo: getLoggedInInfoFromSession(request)
    alt loggedInInfo is null
        Scratch2Action->>Logger: error(Invalid or expired session)
        Scratch2Action->>HttpServletResponse: setStatus(401)
        Scratch2Action-->>User: null
    else loggedInInfo not null
        Scratch2Action->>LoggedInInfo: getLoggedInProviderNo()
        alt providerNo is null
            Scratch2Action->>Logger: error(Provider number not found in session)
            Scratch2Action->>HttpServletResponse: setStatus(401)
            Scratch2Action-->>User: null
        else providerNo not null
            Scratch2Action->>Scratch2Action: getParameter(id)
            alt id is null or empty
                Scratch2Action->>Logger: error(Invalid scratch pad id)
                Scratch2Action-->>User: error view
            else id valid
                Scratch2Action->>ScratchPadDao: find(id)
                alt scratchPad is null
                    ScratchPadDao-->>Scratch2Action: null
                    Scratch2Action->>Scratch2Action: throw IllegalArgumentException
                else scratchPad found
                    ScratchPadDao-->>Scratch2Action: ScratchPad
                    alt providerNo != scratchPad.providerNo
                        Scratch2Action->>Logger: error(User attempted to view scratch pad owned by another)
                        Scratch2Action->>HttpServletResponse: setStatus(403)
                        Scratch2Action-->>User: null
                    else providerNo == scratchPad.providerNo
                        Scratch2Action->>Scratch2Action: setAttribute(ScratchPad)
                        Scratch2Action-->>User: scratchPadVersion view
                    end
                end
            end
        end
    end
Loading

Sequence diagram for Scratch2Action delete with session validation and ownership check

sequenceDiagram
    actor User
    participant Scratch2Action
    participant LoggedInInfo
    participant ScratchPadDao
    participant JSONObject
    participant HttpServletResponse
    participant Logger

    User->>Scratch2Action: delete(request)
    Scratch2Action->>JSONObject: new JSONObject()
    Scratch2Action->>LoggedInInfo: getLoggedInInfoFromSession(request)
    alt loggedInInfo is null
        Scratch2Action->>Logger: error(Invalid or expired session)
        Scratch2Action->>HttpServletResponse: setStatus(401)
        Scratch2Action->>JSONObject: put(success, false)
        Scratch2Action-->>User: jsonResponse(JSONObject)
    else loggedInInfo not null
        Scratch2Action->>LoggedInInfo: getLoggedInProviderNo()
        alt providerNo is null
            Scratch2Action->>Logger: error(Provider number not found in session)
            Scratch2Action->>HttpServletResponse: setStatus(401)
            Scratch2Action->>JSONObject: put(success, false)
            Scratch2Action-->>User: jsonResponse(JSONObject)
        else providerNo not null
            Scratch2Action->>Scratch2Action: getParameter(id)
            alt id is null or empty
                Scratch2Action->>JSONObject: put(success, false)
                Scratch2Action-->>User: jsonResponse(JSONObject)
            else id present
                Scratch2Action->>ScratchPadDao: find(id)
                alt scratch is null
                    ScratchPadDao-->>Scratch2Action: null
                    Scratch2Action->>JSONObject: put(success, false)
                    Scratch2Action-->>User: jsonResponse(JSONObject)
                else scratch found
                    ScratchPadDao-->>Scratch2Action: ScratchPad
                    alt providerNo != scratch.providerNo
                        Scratch2Action->>Logger: error(User attempted to delete scratch pad owned by another)
                        Scratch2Action->>HttpServletResponse: setStatus(403)
                        Scratch2Action->>JSONObject: put(success, false)
                        Scratch2Action-->>User: jsonResponse(JSONObject)
                    else providerNo == scratch.providerNo
                        Scratch2Action->>ScratchPad: setStatus(false)
                        Scratch2Action->>ScratchPadDao: merge(scratch)
                        Scratch2Action->>JSONObject: put(id, encodedId)
                        Scratch2Action->>JSONObject: put(success, true)
                        Scratch2Action-->>User: jsonResponse(JSONObject)
                    end
                end
            end
        end
    end
Loading

Sequence diagram for Scratch2Action execute using LoggedInInfo and provider validation

sequenceDiagram
    actor User
    participant Scratch2Action
    participant LoggedInInfo
    participant HttpServletResponse
    participant Logger

    User->>Scratch2Action: execute(request)
    alt method is delete
        Scratch2Action->>Scratch2Action: delete()
        Scratch2Action-->>User: delete result
    else normal execute
        Scratch2Action->>LoggedInInfo: getLoggedInInfoFromSession(request)
        alt loggedInInfo is null
            Scratch2Action->>Logger: error(Invalid or expired session)
            Scratch2Action->>HttpServletResponse: setStatus(401)
            Scratch2Action-->>User: null
        else loggedInInfo not null
            Scratch2Action->>LoggedInInfo: getLoggedInProviderNo()
            alt providerNo is null
                Scratch2Action->>Logger: error(Provider number not found in session)
                Scratch2Action->>HttpServletResponse: setStatus(401)
                Scratch2Action-->>User: null
            else providerNo not null
                Scratch2Action->>Scratch2Action: getParameter(providerNo)
                alt providerNo equals request providerNo
                    Scratch2Action->>Scratch2Action: process scratch pad create or update
                    Scratch2Action-->>User: success response
                else providerNo mismatch
                    Scratch2Action->>Logger: error(User attempted to act on another provider scratch pad)
                    Scratch2Action->>HttpServletResponse: setStatus(403)
                    Scratch2Action-->>User: null
                end
            end
        end
    end
Loading

Updated class diagram for Scratch2Action session and authorization handling

classDiagram
    class Scratch2Action {
        - ScratchPadDao scratchPadDao
        + String showVersion()
        + String execute()
        + String delete()
    }

    class LoggedInInfo {
        + static LoggedInInfo getLoggedInInfoFromSession(HttpServletRequest request)
        + String getLoggedInProviderNo()
    }

    class ScratchPadDao {
        + ScratchPad find(Integer id)
        + void merge(ScratchPad scratchPad)
    }

    class ScratchPad {
        + String getProviderNo()
        + void setStatus(Boolean status)
    }

    class HttpServletRequest
    class HttpServletResponse {
        + void setStatus(int status)
    }

    class JSONObject {
        + void put(String key, Object value)
    }

    Scratch2Action --> ScratchPadDao : uses
    Scratch2Action --> LoggedInInfo : uses
    Scratch2Action --> HttpServletRequest : reads parameters
    Scratch2Action --> HttpServletResponse : sets status
    Scratch2Action --> JSONObject : builds json responses
    ScratchPadDao --> ScratchPad : manages
    LoggedInInfo --> HttpServletRequest : reads session
Loading

File-Level Changes

Change Details Files
Introduce LoggedInInfo-based authentication/authorization to Scratch2Action methods and enforce ownership checks.
  • Replace direct session attribute access for the current user with LoggedInInfo.getLoggedInInfoFromSession(request) in execute().
  • Add null checks for LoggedInInfo and its provider number in execute(), returning 401 (unauthorized) when session or provider info is missing.
  • Add LoggedInInfo retrieval and provider number validation to showVersion(), returning 401 when the session or provider number is invalid.
  • Implement ownership verification in showVersion() so users can only view scratch pads where the provider number matches the logged-in provider, returning 403 (forbidden) otherwise.
  • Add LoggedInInfo retrieval and provider number validation to delete(), returning 401 and a JSON failure response when session or provider info is invalid.
  • Implement ownership verification in delete() so users can only delete scratch pads they own, returning 403 and a JSON failure response otherwise.
src/main/java/ca/openosp/openo/scratch/Scratch2Action.java
Improve response handling, logging, and encoding for security and clarity.
  • Set HttpServletResponse status codes (401/403) on authentication/authorization failures in showVersion() and delete().
  • Ensure delete() always returns a JSON object with a success flag on error paths, including auth failures.
  • Use OWASP Encode.forJava for log messages that include user-controlled provider numbers and Encode.forHtmlContent when echoing ids in JSON responses.
  • Log authentication and authorization failures with clear messages (invalid session, missing provider number, ownership violations) using MiscUtils.getLogger().
src/main/java/ca/openosp/openo/scratch/Scratch2Action.java

Assessment against linked issues

Issue Objective Addressed Explanation
#1889 Replace raw session attribute access in Scratch2Action with the LoggedInInfo pattern to obtain the logged-in provider number.
#1889 Implement full LoggedInInfo-based session validation in Scratch2Action, including checking that LoggedInInfo is non-null, verifying session expiration via LoggedInInfo.isExpired(), and handling authentication failures appropriately. The PR adds LoggedInInfo.getLoggedInInfoFromSession(request) calls and null checks, and it sets HTTP 401/403 on failures, but it does not call LoggedInInfo.isExpired() or explicitly handle session expiration/invalidating an expired session as required by the guidelines.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 27, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7d56419c-834c-4652-ad8c-917cec555c28

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/issue-1889-20260127-1722
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

@github-actions
Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 2b7d4d4.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@sebastian-j-ibanez sebastian-j-ibanez changed the base branch from develop to maintenance March 13, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use LoggedInInfo session validation in Scratch2Action

2 participants