diff --git a/pkg/connector/actions.go b/pkg/connector/actions.go index 8eedf94a..d5fefb93 100644 --- a/pkg/connector/actions.go +++ b/pkg/connector/actions.go @@ -287,6 +287,18 @@ func (c *GoogleWorkspace) updateUserStatus(ctx context.Context, args *structpb.S return nil, nil, err } + user, err := withRateLimitWaitValue(ctx, func() (*directoryAdmin.User, error) { + return client.GetUserForProvisioning(ctx, userId) + }) + if err != nil { + return nil, nil, fmt.Errorf("google-workspace: failed to get user %s for status update: %w", userId, err) + } + if user.Suspended == isSuspended { + return &structpb.Struct{Fields: map[string]*structpb.Value{ + fieldSuccess: {Kind: &structpb.Value_BoolValue{BoolValue: true}}, + }}, nil, nil + } + // update user.isSuspended state err = withRateLimitWait(ctx, func() error { _, err := client.UpdateUser(ctx, userId, &directoryAdmin.User{ diff --git a/pkg/connector/actions_test.go b/pkg/connector/actions_test.go index 1cfdfabe..60aa8322 100644 --- a/pkg/connector/actions_test.go +++ b/pkg/connector/actions_test.go @@ -236,6 +236,27 @@ func TestDisableEnableUser_IdempotentAndPayload(t *testing.T) { } } +func TestUpdateUserStatus_IsIdempotentForSuspendedUser(t *testing.T) { + state := &testServerState{users: map[string]*testUser{"alice": {Suspended: true, PrimaryEmail: "alice@example.com"}}} + server := newTestServer(state) + defer server.Close() + + dir := newTestDirectoryService(t, server.URL, server.Client()) + c := newTestConnector() + primeServiceCache(c, dir, nil) + + args := &structpb.Struct{Fields: map[string]*structpb.Value{ + argResourceID: {Kind: &structpb.Value_StringValue{StringValue: "alice"}}, + "is_suspended": {Kind: &structpb.Value_BoolValue{BoolValue: true}}, + }} + if _, _, err := c.updateUserStatus(context.Background(), args); err != nil { + t.Fatalf("updateUserStatus: %v", err) + } + if state.putCount != 0 { + t.Fatalf("expected no PUT for an already suspended user, got %d", state.putCount) + } +} + func TestChangePrimaryEmail(t *testing.T) { state := &testServerState{users: map[string]*testUser{"bob": {Suspended: false, PrimaryEmail: "bob@old.example.com"}}} server := newTestServer(state)