Skip to content

feat: sync job title and department user attributes - #28

Open
c1-squire-dev[bot] wants to merge 1 commit into
mainfrom
squire/EPD-2982/onelogin-job-title-department
Open

feat: sync job title and department user attributes#28
c1-squire-dev[bot] wants to merge 1 commit into
mainfrom
squire/EPD-2982/onelogin-job-title-department

Conversation

@c1-squire-dev

@c1-squire-dev c1-squire-dev Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Closes EPD-2982.

Summary

OneLogin exposes title and department on its user object, but the connector never asked the API for them and never surfaced them on the synced user. Policies and automations in C1 that want to key off job title or department had nothing to match on.

This change plumbs both attributes through the user sync:

  • pkg/onelogin/models.go — add Title and Department to the User model.
  • pkg/onelogin/request.go — add title and department to UserFields. The client always sends a fields query param on /api/2/users, and that endpoint returns only the named fields, so the list response would otherwise omit both.
    • This is consistency/future-proofing rather than load-bearing for the feature: userResourceType.List discards the listed object and rebuilds each user from GetUserByID, which sends no fields filter and already returns the full record. The synced profile is populated from that by-ID response. Keeping the two response shapes aligned avoids a trap if the per-user refetch is ever dropped.
  • pkg/connector/user.go — populate job_title and department in the user trait profile.
    • job_title / department are the profile key names already used by sibling connectors (baton-jumpcloud, baton-paylocity, baton-percipio), so the attributes land under a consistent name in C1.
    • Both values are trimmed and omitted when blank, matching how the existing optional manager_user_id / manager_email keys are handled — downstream consumers don't have to special-case empty strings.
    • buildUserProfile now takes *onelogin.User instead of seven positional scalars. The old signature was three string params in a row and growing it further is exactly the swapped-argument hazard called out in CLAUDE.md. It has one caller, so the refactor is local.

No behavior change for users whose OneLogin record leaves title or department unset.

Testing

Added pkg/connector/user_test.go (new) and extended pkg/onelogin/request_test.go:

  • job_title / department are populated in the profile when present.
  • Both keys are omitted entirely when the source value is empty or whitespace-only.
  • Values are trimmed.
  • Existing profile keys (login, user_id, first_name, last_name, manager fields) still populate as before — regression cover for the signature refactor.
  • The built v2.Resource profile carries both attributes end-to-end through parseIntoUserResource.
  • UserFields includes title and department alongside the pre-existing fields.
  • User JSON decoding handles both present and absent title / department.
$ go build ./cmd/baton-onelogin
$ go test ./pkg/... -count=1
ok  github.com/conductorone/baton-onelogin/pkg/connector  0.020s
ok  github.com/conductorone/baton-onelogin/pkg/onelogin   0.008s

10/10 tests pass. go vet ./... clean. golangci-lint run reports no new findings — the 8 remaining SA1019 deprecation warnings (WithUserProfile, WithStatus, WithAppProfile, WithGroupProfile, WithRoleProfile) are all pre-existing on main and untouched here.

Caveats / follow-ups

  • Verified against unit tests only; not run against a live OneLogin tenant. Worth a smoke sync against a real tenant before release to confirm the API returns title / department under those exact JSON keys for the tenant's schema.
  • The 8 pre-existing SA1019 deprecations (trait-level profile/status options moving to resource-level WithResourceProfile / WithResourceStatus) are a separate cleanup — deliberately left alone to keep this diff scoped.
  • OneLogin also exposes company, division, and custom_attributes. Not included, since the request was specifically job title and department.
  • UserFields still omits manager_user_id, which is why List refetches every user via GetUserByID — an N+1 per sync page. Adding it to UserFields would likely let the refetch go away entirely. Out of scope here, but worth a follow-up.

Live Preview

This connector is a CLI binary with no web surface, so there is nothing to preview in-browser. For completeness, the environment's static endpoint is here (serves nothing relevant to this change). Reviewers should verify via go test ./pkg/... or a baton-onelogin sync against a test tenant.

OneLogin exposes `title` and `department` on the user object, but the
connector neither requested them from the API nor surfaced them on the
synced user. Downstream policies and automations that key off job title
or department therefore had nothing to match on.

- Add `Title` and `Department` to the `onelogin.User` model.
- Add `title` and `department` to `UserFields` so the users list endpoint
  actually returns them (that endpoint only returns requested fields).
- Populate `job_title` and `department` in the user trait profile, using
  the profile key names other ConductorOne connectors already use. Both
  are trimmed and omitted when blank, matching the existing treatment of
  the optional manager fields.
- Take `*onelogin.User` in `buildUserProfile` instead of seven positional
  scalars, so adding fields can't silently swap arguments.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
@linear-code

linear-code Bot commented Aug 18, 2026

Copy link
Copy Markdown

EPD-2982

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.

0 participants