Skip to content

[19.4.2 Beta] Assessment History block shows every assessment in the database when PersonId page parameter is an IdKey #6985

Description

@JDShuman

Description

The Assessment History block on a person profile's History tab (RockWeb/Blocks/Crm/AssessmentHistory.ascx.cs) has a data-integrity bug when the page's PersonId parameter is passed as a hashed IdKey rather than a plain integer:

  • It filters correctly when PersonId is a plain integer.
  • It shows every Assessment record in the entire database — attributed to whoever's profile happens to be open — when PersonId is an IdKey instead.
  • This is internal-facing only: it affects staff viewing the person profile's History tab in the Rock admin, not the attendee-facing public profile page, which appears to correctly filter by CurrentPerson rather than relying on an Id/IdKey page parameter. Assessment results are not exposed to the wrong person externally.
  • The practical impact we've seen is staff seeing a person's profile appear to have a large number of pending assessment requests piled up, which reads as though the system is bombarding that attendee with repeated assessment requests — when in reality most or all of those "pending" rows belong to other people entirely and the attendee has no idea any of this is happening.

Root cause (confirmed against source, RockWeb/Blocks/Crm/AssessmentHistory.ascx.cs, BindGrid(), lines 233–238 in both the 19.3.4 and 19.4.2-beta tags):

var personId = PageParameter( PageParameterKey.PersonId ).AsIntegerOrNull();

if ( personId.HasValue )
{
    query = query.Where( a => a.PersonAlias.PersonId == personId.Value );
}

AsIntegerOrNull() returns null when PersonId arrives as a hashed IdKey string rather than an integer. Because personId.HasValue is then false, the surrounding if block is skipped and no .Where() filter is ever applied to the query — it falls through and returns the full, unfiltered Assessment table, which then gets bound to the grid as if it belonged to the current person.

Permalink to the exact lines on the 19.4.2-beta tag: https://github.com/SparkDevNetwork/Rock/blob/19.4.2-beta/RockWeb/Blocks/Crm/AssessmentHistory.ascx.cs#L233-L238

For reference, develop has already replaced this block with a new Obsidian version (Rock.Blocks/Crm/AssessmentHistory.cs, added in commit ec0d1d91d9) that resolves PersonId via PersonService.GetSelect(personKey, selector, allowIntegerIdentifier), which is IdKey-aware. That rewrite isn't in a released 19.3.x/19.4.x tag yet, so it's worth confirming whether it actually fixes this specific failure mode or whether it needs the same null-check treatment.

A cursory search of open and closed issues did not turn up an exact duplicate. #4114 covers a related-sounding but distinct problem (orphaned assessment attributes after a person merge) — different root cause, not the same bug.

Actual Behavior

When the PersonId page parameter on the History tab is an IdKey instead of an integer, the Assessment History block's person filter is silently skipped, and the grid displays every assessment request in the system under whoever's profile is currently being viewed in the staff-facing admin.

Reliably reproducible — confirmed against the actual source of RockWeb/Blocks/Crm/AssessmentHistory.ascx.cs as shipped in the 19.3.4 and 19.4.2-beta tags, and reproduced on the demo site (19.3) and on LCBC's own Rock environment.

Expected Behavior

The Assessment History block should resolve PersonId the same way whether it's passed as an integer or as an IdKey (e.g., using an IdKey-aware lookup such as PersonService.GetSelect), and should never fall back to an unfiltered query just because the parameter didn't parse as a plain integer.

Steps to Reproduce

  1. On the demo site, search for and open Cindy Decker's person profile. Confirm the URL uses an integer PersonId (e.g. /Person/7).
  2. On Cindy's profile, use the Actions button → Request Assessment, select one or more assessments (e.g. DISC, Spiritual Gifts), and submit the request.
  3. If the environment has no communication transport/SMTP configured, the request will end on a "Workflow Processing Error(s): The SMTP host was not specified" page — this is expected and unrelated to the bug.
  4. Go to Cindy's profile History tab (More → History) and confirm the requested assessment(s) appear in the Assessment History block with a status of Pending, correctly attributed to Cindy.
  5. Use the family-member switcher (the name dropdown at the top-left of the profile) to switch to one of Cindy's family members, e.g. Ted Decker. Confirm the URL now shows Ted's own integer PersonId.
  6. On Ted's History tab, confirm the Assessment History block correctly shows no assessments for Ted ("No Assessments Found") — the block behaves correctly here, because PersonId is still an integer.
  7. While still on Ted's profile, use the admin toolbar to add an HTML block to a zone, and set its content to <div>{{ Person.Id | ToIdHash }}</div>. Since Ted is the person in context, this renders Ted's own PersonId as its IdKey equivalent.
  8. Note the IdKey value rendered by the block above — this is Ted's own identifier, just hashed instead of a plain integer.
  9. Replace the integer PersonId page parameter in Ted's own profile URL with that IdKey value from step 8 (i.e., load Ted's History tab, but pass his own IdKey as the PersonId parameter instead of his own integer id).
  10. Observe that the Assessment History block now displays Cindy's pending assessments — and, per the confirmed source, every other assessment in the database — as if they belong to Ted, even though the parameter used was Ted's own valid identity, because AsIntegerOrNull() failed to parse the IdKey and the person filter was skipped entirely.

Note: this isn't limited to viewing someone else's page with their IdKey. Swapping in Cindy's own IdKey for her own integer PersonId on her own profile would trigger the same failure and surface every assessment in the system on her History tab too.

Reliably reproducible on the public demo site (rock.rocksolidchurchdemo.com) as well as on LCBC's own Rock instances, and the root cause above is confirmed directly against the shipped source for both versions.

Issue Confirmation

  • Perform a search on the Github Issues to see if your bug is already reported.
  • Reproduced the problem on a fresh install or on the demo site.

Rock Version

19.3, 19.4

Client Culture Setting

en-US

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions