Harden the Google Analytics account fetch
Three defects, all found reviewing the rebased branch. The connection probe hit /v1alpha/accounts, which any analytics.readonly grant can call, while the driver's first request is the account's accessBindings — that additionally needs Administrator on the account and the manage.users.readonly scope. An Editor connecting, or a user declining the second scope on Google's granular consent screen, probed green and then 403'd on every campaign fetch, leaving the source permanently "Connected" with no rows. The probe now targets the same accessBindings collection the driver reads. A single unreadable property aborted the whole account. A property the token cannot see, or one deleted between the list and the read, threw away every binding already collected; 49 of 50 readable properties are still worth reviewing, so 403 and 404 now skip that property. Anything else still fails the fetch. Fan-out errors named no resource: the account call, the property list and each per-property call all returned the same "unexpected status" string, so a 403 on one subproperty out of forty was unattributable. Errors now carry the account or property ID. The cassette gains a subproperty parented to another property (only reachable through the ancestor filter, so it pins the hierarchy walk that the filter change claimed) and a property returning 403. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -38,7 +38,7 @@ func TestGoogleAnalyticsDriver(t *testing.T) {
|
||||
driver := NewGoogleAnalyticsDriver(client, "123456")
|
||||
records, err := driver.ListAccounts(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.Len(t, records, 3)
|
||||
require.Len(t, records, 4)
|
||||
|
||||
// alice holds an account-level admin binding AND a property-level viewer
|
||||
// binding: roles are merged, deduplicated, sorted, prefix-stripped, and the
|
||||
@@ -62,4 +62,14 @@ func TestGoogleAnalyticsDriver(t *testing.T) {
|
||||
assert.Equal(t, "carol@example.com", carol.Email)
|
||||
assert.False(t, carol.IsAdmin)
|
||||
assert.Equal(t, []string{"analyst"}, carol.Roles)
|
||||
|
||||
// dave holds a binding only on properties/99999, a subproperty parented to
|
||||
// another property rather than to the account. He is reachable only through
|
||||
// the ancestor filter, so his presence is what proves subproperties are
|
||||
// walked. A third property (55555) returns 403 and is skipped rather than
|
||||
// failing the whole account — otherwise these four records would be zero.
|
||||
dave := records[3]
|
||||
assert.Equal(t, "dave@example.com", dave.Email)
|
||||
assert.False(t, dave.IsAdmin)
|
||||
assert.Equal(t, []string{"analyst"}, dave.Roles)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user