Skip to content

fix(steam): populate RawData from Steam player payload (#518)#644

Open
yabanci wants to merge 1 commit into
markbates:masterfrom
yabanci:revive/518-steam-rawdata
Open

fix(steam): populate RawData from Steam player payload (#518)#644
yabanci wants to merge 1 commit into
markbates:masterfrom
yabanci:revive/518-steam-rawdata

Conversation

@yabanci
Copy link
Copy Markdown

@yabanci yabanci commented May 17, 2026

What

Revives and extends @leobrines's #518, which has been sitting MERGEABLE for ~2 years. The gap it identified is still real on master: providers/steam/steam.go:buildUserObject never assigns anything to u.RawData, so the steam provider is the only one in goth that ships a fully empty RawData map. Callers have no way to reach Steam-specific fields without a slot on goth.Usertimecreated, primaryclanid, profileurl, communityvisibilitystate, profilestate, personastate, avatar, avatarmedium.

Change vs. master

- err := json.NewDecoder(r).Decode(&apiResponse)
+ bits, err := io.ReadAll(r)
+ // decode envelope with player as json.RawMessage
+ // unmarshal player once into the typed struct, once into u.RawData

Read the body once, decode the envelope into a typed struct that keeps the player payload as json.RawMessage, then unmarshal that payload twice — into the typed struct (for goth.User fields) and into u.RawData (for everything else). This mirrors what auth0/discord/etc. already do.

Change vs. #518

I credited @leobrines in the commit body and on his PR. Two deltas vs. his patch, both intended as response to the latent quality concern that probably kept this PR from merging:

  1. Original: json.Marshal(&player)json.Unmarshal(b, &u.RawData). Worked, but RawData became a verbatim copy of the six already-typed fields (steamid, personaname, realname, avatarfull, loccountrycode, locstatecode). Steam-only fields stayed unreachable, which is exactly the gap his issue described.
  2. This PR: unmarshal the raw player JSON into u.RawData directly. Full Steam player payload reaches callers. Updated the test fixture to a realistic Steam response and locked the no-slot fields in with explicit RawData assertions so a future refactor can't silently shrink it again.

His httpTestTransport indirection and overall test layout are preserved — those were the right design.

Backward compatibility

Strictly additive. Callers that previously read user.UserID/user.Name/etc. see no change; callers that previously found an empty user.RawData now find a populated map with the full Steam player JSON. No field semantics moved.

Tests

Added Test_FetchUser (extending @leobrines's). Asserts:

  • The six typed fields still land where they always did.
  • The same six values are echoed via RawData (matches consumer expectations from other providers).
  • The fields without a slot on goth.Usercommunityvisibilitystate, profilestate, personastate, primaryclanid, timecreated, profileurl — are in RawData. These are the ones consumers had no way to reach before and are the actual reason RawData matters here.

Verified the new RawData assertions fail on master (the no-slot fields come back <nil>) and pass with this fix applied. Full go test ./... is green across all 50+ providers; go vet ./... is clean.

Closes #518.

The steam provider's buildUserObject never assigned anything to
u.RawData, so callers had no way to read Steam-specific fields without
a slot on goth.User (timecreated, primaryclanid, profileurl,
communityvisibilitystate, profilestate, personastate, avatar,
avatarmedium). Every other provider exposes the upstream response via
RawData; steam was the outlier.

Continues @leobrines's work in markbates#518 with two adjustments so the patch
reflects the spirit of RawData in other providers:

  1. Decode the body once via io.ReadAll, then unmarshal the player
     into both the typed struct and u.RawData. The original PR
     marshalled the already-typed struct back to JSON and decoded that
     into the map, which made RawData a verbatim duplicate of the six
     typed fields and dropped everything else Steam returned.

  2. Expanded the test fixture beyond the six fields to a realistic
     player payload and locked the no-slot fields in with explicit
     RawData assertions, so a future refactor can't silently shrink
     the response again.

Verified the new assertions fail on master and pass with this change.
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.

1 participant