googleapis / google-api-nodejs-client

Google's officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included.
https://googleapis.dev/nodejs/googleapis/latest/
Apache License 2.0
11.26k stars 1.91k forks source link

How to list all Google Workspace users? #3454

Closed p5 closed 3 months ago

p5 commented 3 months ago

I am trying to create a script that revokes all Google Workspace sessions for all users in my organization, but it's failing with "Invalid Input" when trying to get a list of users in my directory.

Please could you help identify what additional inputs are required, as from the documentation, it seemed like the only one was "customer" (or "domain").

Code:

import { google } from "googleapis";
import path from "path";

const revokeSessionsHandler = async (req: Request) => {
  const auth = await google.auth.getClient({
    keyFile: path.join(__dirname, '../../../../service-account.json'),
    scopes: ["https://www.googleapis.com/auth/admin.directory.user"],
  });

  const admin = google.admin({ version: "directory_v1", auth });

  const params = {
    customer: "my_customer",
  };

  try {
    const res = await admin.users.list(params);

    console.log("Response: ", res);
    return { status: 200, body: res };
  } catch (error) {
    console.error("Error fetching users:", error);

    return { status: 500 };
  }
};

export { revokeSessionsHandler };

Error:

``` config: { url: 'https://admin.googleapis.com/admin/directory/v1/users?customer=my_customer', method: 'GET', userAgentDirectives: [ [Object] ], paramsSerializer: [Function (anonymous)], headers: { 'x-goog-api-client': 'gdcl/7.0.1 gl-node/20.11.1', 'Accept-Encoding': 'gzip', 'User-Agent': 'google-api-nodejs-client/7.0.1 (gzip)', Authorization: 'Bearer ' }, params: { customer: 'my_customer' }, validateStatus: [Function (anonymous)], retry: true, responseType: 'unknown', errorRedactor: [Function: defaultErrorRedactor], retryConfig: { currentRetryAttempt: 0, retry: 3, httpMethodsToRetry: [Array], noResponseRetries: 2, statusCodesToRetry: [Array] } }, response: { config: { url: 'https://admin.googleapis.com/admin/directory/v1/users?customer=my_customer', method: 'GET', userAgentDirectives: [Array], paramsSerializer: [Function (anonymous)], headers: [Object], params: [Object], validateStatus: [Function (anonymous)], retry: true, responseType: 'unknown', errorRedactor: [Function: defaultErrorRedactor] }, data: { error: [Object] }, headers: { 'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000', 'cache-control': 'private', 'content-encoding': 'gzip', 'content-type': 'application/json; charset=UTF-8', date: 'Wed, 13 Mar 2024 12:33:38 GMT', server: 'ESF', 'transfer-encoding': 'chunked', vary: 'Origin, X-Origin, Referer', 'x-content-type-options': 'nosniff', 'x-frame-options': 'SAMEORIGIN', 'x-xss-protection': '0' }, status: 400, statusText: 'Bad Request', request: { responseURL: 'https://admin.googleapis.com/admin/directory/v1/users?customer=my_customer' } }, error: undefined, status: 400, code: 400, errors: [ { message: 'Invalid Input', domain: 'global', reason: 'invalid' } ], [Symbol(gaxios-gaxios-error)]: '6.3.0' } ```

Version information:

``` "googleapis@npm:^133.0.0": version: 133.0.0 resolution: "googleapis@npm:133.0.0" dependencies: google-auth-library: "npm:^9.0.0" googleapis-common: "npm:^7.0.0" checksum: 10c0/c46f9971f189f8551006aab2d25a788de237dce1bfaf20ddd19c6b4cf891468b477a610ae86470065b7481df68874998ad09862ff4ccb623803bce42f0f4dea0 languageName: node linkType: hard ```
p5 commented 3 months ago

So I needed to do two things:

  1. Setup domain-wide delegation on the service account through Google Workspace Admin console
  2. Set clientSettings.subject in the getClient() function to impersonate a user in the organization with the permissions you require.