Skip to content

[BACK-2780] Address code review feedback (attribute merge fix + cleanup) - #967

Open
toddkazakov wants to merge 1 commit into
jimmy/BACK-2780-new-profiles-endpointfrom
todd/BACK-2780-review-fixes
Open

[BACK-2780] Address code review feedback (attribute merge fix + cleanup)#967
toddkazakov wants to merge 1 commit into
jimmy/BACK-2780-new-profiles-endpointfrom
todd/BACK-2780-review-fixes

Conversation

@toddkazakov

Copy link
Copy Markdown
Contributor

Addresses the code review feedback from the 2026-08-07 review on #698. Targets jimmy/BACK-2780-new-profiles-endpoint so it can be merged into that PR.

Bug fixes

  • Profile attribute merge (user/keycloak/client.go): UpdateUser now removes all profile-owned attributes from the merged attribute map before applying Profile.ToAttributes(), so clearing a profile field actually removes the stale attribute in keycloak while non-profile attributes are still preserved. Attribute names are now constants in user/profile.go with RemoveProfileAttributes as the single source of truth, covered by new tests in user/profile_test.go.
  • terms_and_conditions round-trip (drive-by fix found while fixing the above): UpdateUser wrote TermsAccepted in the 2006-01-02T15:04:05-07:00 format into an attribute that is read as a unix timestamp string, so any profile update silently corrupted the terms-accepted attribute. It is now converted back to a unix timestamp string on write; if conversion fails the existing attribute value is kept.

Cleanup, per inline comments

  • User: removed Emails (always empty), PwHash, Hash, PasswordExists, and all bson tags (the struct never touches mongo); removed unused IsClinic, IsClinician, AreTermsAccepted, and IsCustodialAccount (only populated the removed PwHash).
  • IsUnclaimedCustodialEmail is now called in the keycloak client: unclaimed custodial placeholder emails are no longer exposed as the account's username. On update, a nil username is omitted from the keycloak payload, so the stored username is unaffected.
  • User id validation consolidated: user.ValidateID/user.IsValidID own the (single) regexp and auth.ValidateUserID delegates to it. I kept the stricter auth pattern (lowercase-only), so the user package no longer accepts uppercase hex in the uuid form — keycloak ids are lowercase so this should have no practical effect.
  • UserAccessor slimmed: unused FindUser and FindUsersWithIds removed (along with the now-orphaned GetUserByEmail in the keycloak client), and FindUserById replaced by embedding the existing user.Client interface (Get). Mocks regenerated.
  • Moved keycloak-only code out of the top-level user package into user/keycloak: TokenIntrospectionResult, AccessTokenCustomClaims, RealmAccess, IsServerToken, and the timestamp helpers from user/timeutil.go (now unexported; ParseTimestamp and the exported wrappers had no remaining users).
  • Moved LegacySeagullProfileRepository from auth/store/mongo to a new user/store/mongo package, next to the user package that owns LegacySeagullDocument. I used a store/mongo subpackage rather than the user package itself to keep the mongo driver dependency out of the widely imported core package — happy to move it elsewhere.
  • Removed the unused username parameter of ProfileFromAttributes (it only existed for the previously removed legacy email population).
  • Removed the userlib import alias in user/keycloak and renamed shadowing locals instead.

Not addressed (needs discussion)

  • has_custodian attribute → custodial role: not changed here. The attribute exists so the keycloak fake-child-migration extension can filter users, so replacing it with the custodial_account realm role needs a coordinated change in that extension (and the role currently means "unclaimed account", which is not quite the same as "has a custodian in the profile"). Suggest resolving this on the review thread first.

Testing

GOTEST_PKGS="./user/... ./auth/... ./data/raw/..." make test-go passes; go build ./... and go vet ./... are clean; goimports -local github.com/tidepool-org/platform applied to all touched files.

- Fix profile attribute merge bug: clear existing profile attributes before
  applying the updated profile's attributes so cleared fields no longer
  retain stale values in keycloak (introduces RemoveProfileAttributes and
  attribute name constants as a single source of truth)
- Fix terms_and_conditions round-trip: convert the terms accepted timestamp
  back to a unix timestamp string when updating a user, matching the format
  read by newUserFromGocloakUser
- Remove unused User fields (Emails, PwHash, Hash, PasswordExists) and
  methods (IsClinic, IsClinician, IsCustodialAccount, AreTermsAccepted)
- Remove bson tags from User since it is never stored in mongo
- Call IsUnclaimedCustodialEmail in the keycloak client so unclaimed
  custodial placeholder emails are not exposed as the account username
- Consolidate user id validation: user.ValidateID is the single source of
  truth, auth.ValidateUserID delegates to it
- Slim UserAccessor: remove unused FindUser/FindUsersWithIds, replace
  FindUserById with the embedded user.Client interface (Get)
- Move keycloak-specific types (TokenIntrospectionResult et al) and time
  helpers from the user package to user/keycloak
- Move LegacySeagullProfileRepository from auth/store/mongo to
  user/store/mongo
- Drop the unused username parameter of ProfileFromAttributes
- Remove the userlib import alias in user/keycloak per import conventions
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (4)
  • master
  • main
  • develop
  • release.*

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 431f074c-945e-46c4-a9fd-4b2398679fb8

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

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.

@toddkazakov
toddkazakov requested a review from lostlevels August 7, 2026 09:31
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