Resolve the Segment workspace name and reuse listed permissions
Two corrections, both settled from Segment's published OpenAPI document
and their own client code rather than guessed.
The registration claimed the Public API exposes no workspace-name
endpoint on the token's scope. That is wrong: Get Workspace is the API
root, GET /, returning data.workspace.name for the workspace the token
is bound to — the base URL already encodes the US/EU region, so the URL
is the whole request. Without a resolver an organization running a prod
and a staging workspace saw two rows both named "Segment".
The per-user GET /users/{id} is what makes a large workspace exceed the
per-source budget, and it exists only to read permissions[].roleName.
Both endpoints return the same UserV1 schema, on which permissions is
declared but optional, so whether the list populates it is a server
behaviour no specification settles. Rather than assume, the list
response is now decoded for permissions and the per-user request is
issued only when the field is absent. Today Segment omits it — their own
Terraform provider's mock returns /users without permissions and
/users/{id} with them — so behaviour is unchanged; if that ever changes
the extra round trip disappears on its own. An empty-but-present array
is authoritative, meaning a user with no roles, not a missing field.
Page size stays at 200: the 1-1000 range is prose in the pagination
guide, the schema sets no maximum, and the migration guide says 200.
Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -59,6 +59,13 @@ type segmentUser struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
// Permissions is declared on the shared UserV1 schema that both /users
|
||||
// and /users/{id} return, but is optional and today only populated by
|
||||
// the single-user read. Decoding it here means the driver uses whatever
|
||||
// the list gives it rather than assuming: nil (field absent) triggers the
|
||||
// per-user fetch, non-nil — including an empty array for a user with no
|
||||
// roles — is taken as authoritative.
|
||||
Permissions []segmentPermission `json:"permissions"`
|
||||
}
|
||||
|
||||
type segmentPermission struct {
|
||||
@@ -126,9 +133,12 @@ func (d *SegmentDriver) ListAccounts(ctx context.Context) ([]AccountRecord, erro
|
||||
|
||||
seen[strings.ToLower(email)] = struct{}{}
|
||||
|
||||
perms, err := d.userPermissions(ctx, base, u.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list segment permissions for user %q: %w", u.ID, err)
|
||||
perms := u.Permissions
|
||||
if perms == nil {
|
||||
perms, err = d.userPermissions(ctx, base, u.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list segment permissions for user %q: %w", u.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
roles, isAdmin := segmentRolesAndAdmin(perms)
|
||||
|
||||
Reference in New Issue
Block a user