Skip to content

Migrate off deprecated trait profile/status attributes - #50

Merged
laurenleach merged 1 commit into
mainfrom
lauren/migrate-deprecated-trait-attrs
Aug 7, 2026
Merged

Migrate off deprecated trait profile/status attributes#50
laurenleach merged 1 commit into
mainfrom
lauren/migrate-deprecated-trait-attrs

Conversation

@laurenleach

Copy link
Copy Markdown
Contributor

baton-sdk v0.20.6 moved profile, status, and created_at off the trait
messages onto attributes on Resource, deprecating the trait-level options and
getters. staticcheck flags every remaining call with SA1019, so verify / lint
is red on main.

This migrates the connector to the resource-level API:

  • With{User,Group,Role,App}Profile -> WithResourceProfile
  • WithStatus / WithDetailedStatus -> WithResourceStatus
  • WithCreatedAt / WithSecretCreatedAt -> WithResourceCreatedAt
  • trait GetProfile() / GetStatus() reads -> the equivalent read on the resource

The option type changes from a *TraitOption to a ResourceOption, so the calls
move out of the trait slice and into the variadic tail of the New*Resource call.
The two status enums are numerically identical, so the values map 1:1. Non-deprecated
trait data (login, aliases, emails, secret type/expiry) is untouched.

No behavioural change intended: the deprecated options already populated the
resource-level fields. golangci-lint run ./... reports 0 issues after this
change, and the package tests pass.

baton-sdk v0.20.6 moved `profile`, `status`, and `created_at` off the trait
messages onto attributes on `Resource`, deprecating the trait-level options and
getters. staticcheck flags every remaining call with `SA1019`, so `verify / lint`
is red on `main`.

This migrates the connector to the resource-level API:

- `With{User,Group,Role,App}Profile` -> `WithResourceProfile`
- `WithStatus` / `WithDetailedStatus` -> `WithResourceStatus`
- `WithCreatedAt` / `WithSecretCreatedAt` -> `WithResourceCreatedAt`
- trait `GetProfile()` / `GetStatus()` reads -> the equivalent read on the resource

The option type changes from a `*TraitOption` to a `ResourceOption`, so the calls
move out of the trait slice and into the variadic tail of the `New*Resource` call.
The two status enums are numerically identical, so the values map 1:1. Non-deprecated
trait data (login, aliases, emails, secret type/expiry) is untouched.

No behavioural change intended: the deprecated options already populated the
resource-level fields. `golangci-lint run ./...` reports 0 issues after this
change, and the package tests pass.
Comment thread pkg/connector/user.go
rs.WithResourceProfile(profile),
rs.WithResourceStatus(v2.Status_RESOURCE_STATUS_ENABLED, ""),
rs.WithParentResourceID(parentResourceID),
rs.WithExternalID(&v2.ExternalId{Id: user.ID}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion: rs.WithExternalID is also deprecated in this SDK version (resource.go: "Deprecated. This field is no longer used.") and nothing in this connector reads GetExternalId() — Grant/Revoke here use principal.Id.Resource / grant.Principal.Id.Resource. staticcheck doesn't flag it only because the SDK's comment isn't in the Deprecated: paragraph form, so it slipped past the SA1019 sweep. Consider dropping it in this same cleanup.

Comment thread pkg/connector/group.go
}

groupId, ok := rs.GetProfileStringValue(groupTrait.Profile, "group_id")
groupId, ok := rs.GetProfileStringValue(rs.GetProfile(resource), "group_id")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion: Grants now depends on the profile round-tripping through the resource-level field rather than the group trait, and there is no test covering it (license_test.go only asserts LicenseProfileTrait). A small test that builds groupResource(...) and asserts rs.GetProfileStringValue(rs.GetProfile(res), "group_id") returns the ID would lock in this migration and guard the grant path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

GetProfile will fall back to group trait if resource profile is not set

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: Migrate off deprecated trait profile/status attributes

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base 2100022cfcac.
Review mode: full
View review run

Review Summary

Scanned the full PR diff (3 files, 7 additions / 12 deletions) for security and correctness. The migration is faithful to baton-sdk v0.22.0: WithResourceProfile and WithResourceStatus are ResourceOptions applied before the trait options, and the SDK's trait-to-resource sync helpers only fill fields that are still unset, so nothing already set is overwritten; Status_RESOURCE_STATUS_ENABLED (1) matches the previous UserTrait_Status_STATUS_ENABLED, and NewUserTrait still defaults the trait status to enabled, so the emitted UserTrait is unchanged. rs.GetProfile and GetProfileStringValue are nil-safe and fall back to trait-level profiles for previously synced data, so groupBuilder.Grants keeps working across the upgrade. go.mod/go.sum were not touched, and no other call sites of the deprecated options remain under pkg/. Two non-blocking suggestions below.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • pkg/connector/user.go:64rs.WithExternalID is also deprecated in this SDK version and is unused by this connector's provisioning paths; it evaded the SA1019 sweep only because of the SDK comment's format.
  • pkg/connector/group.go:98 — no test covers the profile now round-tripping through the resource-level field, which Grants depends on.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/connector/user.go`:
- Around line 64: the call to rs.WithExternalID uses an option the SDK documents as
  deprecated and no longer used ("WithExternalID: Deprecated. This field is no longer
  used." in pkg/types/resource/resource.go). staticcheck does not report it because the
  deprecation notice is not written as a "Deprecated: " paragraph, so it was missed by
  this SA1019 cleanup. Nothing in this repo reads GetExternalId(): licenseBuilder
  Grant/Revoke and groupBuilder Grant/Revoke use principal.Id.Resource and
  grant.Principal.Id.Resource. Remove the rs.WithExternalID option from userResource as
  part of the same deprecation cleanup, and drop any import it leaves unused.

In `pkg/connector/group.go`:
- Around line 98: groupBuilder.Grants now resolves group_id from the resource-level
  profile via rs.GetProfile(resource) instead of the group trait, and nothing tests that
  path; pkg/connector/license_test.go only asserts the LicenseProfileTrait. Add a
  table-driven test in pkg/connector that calls groupResource(...) (and optionally
  userResource(...)) and asserts rs.GetProfileStringValue(rs.GetProfile(res),
  "group_id") returns the group ID, and that rs.GetStatus(res).GetStatus() is
  v2.Status_RESOURCE_STATUS_ENABLED for users. This pins the migrated behavior so a
  future refactor cannot silently drop the profile that the grant path depends on.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No blocking issues found.

@laurenleach
laurenleach merged commit 8286bee into main Aug 7, 2026
11 checks passed
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